sync code with last improvements from OpenBSD

This commit is contained in:
purplerain 2023-09-08 20:30:31 +00:00
parent 0e5a54c21a
commit 9bb7c570b7
Signed by: purplerain
GPG key ID: F42C07F07E2E35B7
33 changed files with 1190 additions and 596 deletions

View file

@ -1928,7 +1928,9 @@
./usr/share/man/man3/EVP_DigestVerifyInit.3
./usr/share/man/man3/EVP_EncodeInit.3
./usr/share/man/man3/EVP_EncryptInit.3
./usr/share/man/man3/EVP_MD_CTX_ctrl.3
./usr/share/man/man3/EVP_MD_meth_new.3
./usr/share/man/man3/EVP_MD_nid.3
./usr/share/man/man3/EVP_OpenInit.3
./usr/share/man/man3/EVP_PKCS82PKEY.3
./usr/share/man/man3/EVP_PKEY_CTX_ctrl.3

View file

@ -1,4 +1,4 @@
.\" $OpenBSD: EVP_DigestInit.3,v 1.30 2023/09/07 14:22:11 schwarze Exp $
.\" $OpenBSD: EVP_DigestInit.3,v 1.31 2023/09/07 19:59:58 schwarze Exp $
.\" full merge up to: OpenSSL 7f572e95 Dec 2 13:57:04 2015 +0000
.\" selective merge up to: OpenSSL 24a535ea Sep 22 13:14:20 2020 +0100
.\"
@ -89,7 +89,6 @@
.Nm EVP_DigestInit ,
.Nm EVP_DigestFinal ,
.Nm EVP_MD_CTX_copy ,
.Nm EVP_MAX_MD_SIZE ,
.Nm EVP_MD_CTX_md ,
.Nm EVP_md_null ,
.Nm EVP_sha224 ,
@ -177,7 +176,6 @@
.Fa "EVP_MD_CTX *out"
.Fa "EVP_MD_CTX *in"
.Fc
.Fd #define EVP_MAX_MD_SIZE 64 /* SHA512 */
.Ft const EVP_MD *
.Fo EVP_MD_CTX_md
.Fa "const EVP_MD_CTX *ctx"
@ -460,14 +458,19 @@ or
if
.Fa ctx
is
.Dv NULL .
.Dv NULL
or does not have any message digest algorithm assigned yet.
.Pp
.Fn EVP_md_null
.Fn EVP_md_null ,
.Fn EVP_sha224 ,
.Fn EVP_sha256 ,
.Fn EVP_sha384 ,
.Fn EVP_sha512 ,
.Fn EVP_sha512_224 ,
.Fn EVP_sha512_256 ,
and
.Fn EVP_ripemd160
return pointers to the corresponding
.Vt EVP_MD
structures.
return pointers to constant static objects owned by the library.
.Pp
.Fn EVP_get_digestbyname ,
.Fn EVP_get_digestbynid ,
@ -551,9 +554,8 @@ main(int argc, char *argv[])
.Sh HISTORY
.Fn EVP_DigestInit ,
.Fn EVP_DigestUpdate ,
.Fn EVP_DigestFinal ,
and
.Dv EVP_MAX_MD_SIZE
.Fn EVP_DigestFinal
first appeared in SSLeay 0.5.1.
.Fn EVP_md_null
and

View file

@ -1,4 +1,4 @@
.\" $OpenBSD: EVP_MD_CTX_ctrl.3,v 1.1 2023/09/07 14:22:11 schwarze Exp $
.\" $OpenBSD: EVP_MD_CTX_ctrl.3,v 1.2 2023/09/07 19:28:37 schwarze Exp $
.\" full merge up to: OpenSSL man3/EVP_DigestInit.pod
.\" 24a535ea Sep 22 13:14:20 2020 +0100
.\"
@ -247,6 +247,12 @@ returns the bitwise OR of the
.Fa flags
argument and the flags set in
.Fa ctx .
.Pp
.Fn EVP_MD_CTX_pkey_ctx
and
.Fn EVP_MD_CTX_md_data
return pointers to storage owned by
.Fa ctx .
.Sh SEE ALSO
.Xr evp 3 ,
.Xr EVP_DigestInit 3 ,

View file

@ -1,4 +1,4 @@
.\" $OpenBSD: EVP_PKEY_cmp.3,v 1.12 2021/10/19 17:42:49 schwarze Exp $
.\" $OpenBSD: EVP_PKEY_cmp.3,v 1.13 2023/09/08 11:37:58 schwarze Exp $
.\" full merge up to: OpenSSL 05ea606a May 20 20:52:46 2016 -0400
.\" selective merge up to: OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400
.\"
@ -67,7 +67,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd $Mdocdate: October 19 2021 $
.Dd $Mdocdate: September 8 2023 $
.Dt EVP_PKEY_CMP 3
.Os
.Sh NAME
@ -75,6 +75,10 @@
.Nm EVP_PKEY_copy_parameters ,
.Nm EVP_PKEY_cmp_parameters ,
.Nm EVP_PKEY_cmp
.\" .Nm EVP_PKEY_save_parameters is intentionally undocumented
.\" because nothing uses it according to codesearch.debian.net
.\" and it only affects X509_PUBKEY_set(3) for DSA and GOST2001 keys,
.\" resulting in incomplete output without the public key parameters.
.Nd public key parameter and comparison functions
.Sh SYNOPSIS
.In openssl/evp.h

View file

@ -1,4 +1,4 @@
# $OpenBSD: scp.sh,v 1.18 2023/01/13 04:47:34 dtucker Exp $
# $OpenBSD: scp.sh,v 1.19 2023/09/08 05:50:57 djm Exp $
# Placed in the Public Domain.
tid="scp"
@ -25,13 +25,25 @@ scpclean() {
chmod 755 ${DIR} ${DIR2} ${DIR3}
}
# Create directory structure for recursive copy tests.
forest() {
scpclean
rm -rf ${DIR2}
cp ${DATA} ${DIR}/copy
ln -s ${DIR}/copy ${DIR}/copy-sym
mkdir ${DIR}/subdir
cp ${DATA} ${DIR}/subdir/copy
ln -s ${DIR}/subdir ${DIR}/subdir-sym
}
for mode in scp sftp ; do
tag="$tid: $mode mode"
if test $mode = scp ; then
scpopts="-O -q -S ${OBJ}/scp-ssh-wrapper.scp"
else
scpopts="-s -D ${SFTPSERVER}"
scpopts="-qs -D ${SFTPSERVER}"
fi
verbose "$tag: simple copy local file to local file"
scpclean
$SCP $scpopts ${DATA} ${COPY} || fail "copy failed"
@ -91,21 +103,19 @@ for mode in scp sftp ; do
cmp ${COPY} ${DIR}/copy || fail "corrupted copy"
verbose "$tag: recursive local dir to remote dir"
scpclean
rm -rf ${DIR2}
cp ${DATA} ${DIR}/copy
forest
$SCP $scpopts -r ${DIR} somehost:${DIR2} || fail "copy failed"
diff ${DIFFOPT} ${DIR} ${DIR2} || fail "corrupted copy"
verbose "$tag: recursive local dir to local dir"
scpclean
forest
rm -rf ${DIR2}
cp ${DATA} ${DIR}/copy
$SCP $scpopts -r ${DIR} ${DIR2} || fail "copy failed"
diff ${DIFFOPT} ${DIR} ${DIR2} || fail "corrupted copy"
verbose "$tag: recursive remote dir to local dir"
scpclean
forest
rm -rf ${DIR2}
cp ${DATA} ${DIR}/copy
$SCP $scpopts -r somehost:${DIR} ${DIR2} || fail "copy failed"

View file

@ -1,10 +1,8 @@
# $OpenBSD: scp3.sh,v 1.4 2023/01/13 04:47:34 dtucker Exp $
# $OpenBSD: scp3.sh,v 1.5 2023/09/08 06:10:57 djm Exp $
# Placed in the Public Domain.
tid="scp3"
set -x
COPY2=${OBJ}/copy2
DIR=${COPY}.dd
DIR2=${COPY}.dd2
@ -22,6 +20,17 @@ scpclean() {
chmod 755 ${DIR} ${DIR2}
}
# Create directory structure for recursive copy tests.
forest() {
scpclean
rm -rf ${DIR2}
cp ${DATA} ${DIR}/copy
ln -s ${DIR}/copy ${DIR}/copy-sym
mkdir ${DIR}/subdir
cp ${DATA} ${DIR}/subdir/copy
ln -s ${DIR}/subdir ${DIR}/subdir-sym
}
for mode in scp sftp ; do
scpopts="-F${OBJ}/ssh_proxy -S ${SSH} -q"
tag="$tid: $mode mode"
@ -43,9 +52,7 @@ for mode in scp sftp ; do
cmp ${COPY} ${DIR}/copy || fail "corrupted copy"
verbose "$tag: recursive remote dir to remote dir"
scpclean
rm -rf ${DIR2}
cp ${DATA} ${DIR}/copy
forest
$SCP $scpopts -3r hostA:${DIR} hostB:${DIR2} || fail "copy failed"
diff -r ${DIR} ${DIR2} || fail "corrupted copy"
diff -r ${DIR2} ${DIR} || fail "corrupted copy"

View file

@ -1,4 +1,4 @@
.\" $OpenBSD: bsd.port.mk.5,v 1.620 2023/09/07 17:26:14 espie Exp $
.\" $OpenBSD: bsd.port.mk.5,v 1.621 2023/09/07 23:32:56 espie Exp $
.\"
.\" Copyright (c) 2000-2008 Marc Espie
.\"
@ -4347,8 +4347,6 @@ and
.Bl -tag -width Ds
.It Pa ../Makefile.inc
Common Makefile fragment for a set of ports, included automatically.
.It Pa /cdrom/distfiles
Default path to a CD-ROM (or other media) full of distribution files.
.It Pa ${PORTSDIR}/distfiles
Default setup of ${DISTDIR}.
.It Pa ${DISTDIR}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: kern_exit.c,v 1.213 2023/09/04 13:18:41 claudio Exp $ */
/* $OpenBSD: kern_exit.c,v 1.214 2023/09/08 09:06:31 claudio Exp $ */
/* $NetBSD: kern_exit.c,v 1.39 1996/04/22 01:38:25 christos Exp $ */
/*
@ -157,12 +157,10 @@ exit1(struct proc *p, int xexit, int xsig, int flags)
}
/* unlink ourselves from the active threads */
SCHED_LOCK(s);
TAILQ_REMOVE(&pr->ps_threads, p, p_thr_link);
SCHED_UNLOCK(s);
mtx_enter(&pr->ps_mtx);
TAILQ_REMOVE(&pr->ps_threads, p, p_thr_link);
pr->ps_threadcnt--;
wake = (pr->ps_single && pr->ps_singlecnt == pr->ps_threadcnt);
mtx_leave(&pr->ps_mtx);
if (wake)
@ -170,9 +168,11 @@ exit1(struct proc *p, int xexit, int xsig, int flags)
if ((p->p_flag & P_THREAD) == 0) {
/* main thread gotta wait because it has the pid, et al */
/* XXX locking depends on kernel lock here. */
mtx_enter(&pr->ps_mtx);
while (pr->ps_threadcnt > 0)
tsleep_nsec(&pr->ps_threads, PWAIT, "thrdeath", INFSLP);
msleep_nsec(&pr->ps_threads, &pr->ps_mtx, PWAIT,
"thrdeath", INFSLP);
mtx_leave(&pr->ps_mtx);
if (pr->ps_flags & PS_PROFIL)
stopprofclock(pr);
}
@ -345,8 +345,10 @@ exit1(struct proc *p, int xexit, int xsig, int flags)
/* just a thread? detach it from its process */
if (p->p_flag & P_THREAD) {
/* scheduler_wait_hook(pr->ps_mainproc, p); XXX */
mtx_enter(&pr->ps_mtx);
if (pr->ps_threadcnt == 0)
wakeup(&pr->ps_threads);
mtx_leave(&pr->ps_mtx);
}
/* Release the thread's read reference of resource limit structure. */

View file

@ -1,4 +1,4 @@
/* $OpenBSD: kern_fork.c,v 1.250 2023/09/04 13:18:41 claudio Exp $ */
/* $OpenBSD: kern_fork.c,v 1.251 2023/09/08 09:06:31 claudio Exp $ */
/* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */
/*
@ -519,7 +519,7 @@ thread_fork(struct proc *curp, void *stack, void *tcb, pid_t *tidptr,
struct proc *p;
pid_t tid;
vaddr_t uaddr;
int s, error;
int error;
if (stack == NULL)
return EINVAL;
@ -561,11 +561,8 @@ thread_fork(struct proc *curp, void *stack, void *tcb, pid_t *tidptr,
LIST_INSERT_HEAD(&allproc, p, p_list);
LIST_INSERT_HEAD(TIDHASH(p->p_tid), p, p_hash);
SCHED_LOCK(s);
TAILQ_INSERT_TAIL(&pr->ps_threads, p, p_thr_link);
SCHED_UNLOCK(s);
mtx_enter(&pr->ps_mtx);
TAILQ_INSERT_TAIL(&pr->ps_threads, p, p_thr_link);
pr->ps_threadcnt++;
/*

View file

@ -1,4 +1,4 @@
/* $OpenBSD: kern_resource.c,v 1.78 2023/08/29 16:19:34 claudio Exp $ */
/* $OpenBSD: kern_resource.c,v 1.79 2023/09/08 09:06:31 claudio Exp $ */
/* $NetBSD: kern_resource.c,v 1.38 1996/10/23 07:19:38 matthias Exp $ */
/*-
@ -212,11 +212,13 @@ donice(struct proc *curp, struct process *chgpr, int n)
if (n < chgpr->ps_nice && suser(curp))
return (EACCES);
chgpr->ps_nice = n;
SCHED_LOCK(s);
mtx_enter(&chgpr->ps_mtx);
TAILQ_FOREACH(p, &chgpr->ps_threads, p_thr_link) {
SCHED_LOCK(s);
setpriority(p, p->p_estcpu, n);
SCHED_UNLOCK(s);
}
SCHED_UNLOCK(s);
mtx_leave(&chgpr->ps_mtx);
return (0);
}
@ -476,8 +478,9 @@ dogetrusage(struct proc *p, int who, struct rusage *rup)
struct process *pr = p->p_p;
struct proc *q;
switch (who) {
KERNEL_ASSERT_LOCKED();
switch (who) {
case RUSAGE_SELF:
/* start with the sum of dead threads, if any */
if (pr->ps_ru != NULL)

View file

@ -1,4 +1,4 @@
/* $OpenBSD: kern_sig.c,v 1.314 2023/09/04 13:18:41 claudio Exp $ */
/* $OpenBSD: kern_sig.c,v 1.315 2023/09/08 09:06:31 claudio Exp $ */
/* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */
/*
@ -2105,12 +2105,11 @@ single_thread_set(struct proc *p, enum single_thread_mode mode, int wait)
}
pr->ps_singlecnt = 1; /* count ourselfs in already */
pr->ps_single = p;
mtx_leave(&pr->ps_mtx);
SCHED_LOCK(s);
TAILQ_FOREACH(q, &pr->ps_threads, p_thr_link) {
if (q == p)
continue;
SCHED_LOCK(s);
if (q->p_flag & P_WEXIT) {
if (mode == SINGLE_EXIT && q->p_stat == SSTOP)
setrunnable(q);
@ -2146,10 +2145,9 @@ single_thread_set(struct proc *p, enum single_thread_mode mode, int wait)
signotify(q);
break;
}
SCHED_UNLOCK(s);
}
SCHED_UNLOCK(s);
mtx_enter(&pr->ps_mtx);
pr->ps_singlecnt += count;
mtx_leave(&pr->ps_mtx);
@ -2194,11 +2192,10 @@ single_thread_clear(struct proc *p, int flag)
KASSERT(pr->ps_single == p);
KASSERT(curproc == p);
/* can do this without holding pr->ps_mtx since no concurrency */
mtx_enter(&pr->ps_mtx);
pr->ps_single = NULL;
atomic_clearbits_int(&pr->ps_flags, PS_SINGLEUNWIND | PS_SINGLEEXIT);
SCHED_LOCK(s);
TAILQ_FOREACH(q, &pr->ps_threads, p_thr_link) {
if (q == p || (q->p_flag & P_SUSPSINGLE) == 0)
continue;
@ -2209,6 +2206,7 @@ single_thread_clear(struct proc *p, int flag)
* then clearing that either makes it runnable or puts
* it back into some sleep queue
*/
SCHED_LOCK(s);
if (q->p_stat == SSTOP && (q->p_flag & flag) == 0) {
if (q->p_wchan == NULL)
setrunnable(q);
@ -2217,8 +2215,9 @@ single_thread_clear(struct proc *p, int flag)
q->p_stat = SSLEEP;
}
}
SCHED_UNLOCK(s);
}
SCHED_UNLOCK(s);
mtx_leave(&pr->ps_mtx);
}
void

View file

@ -1,4 +1,4 @@
/* $OpenBSD: kern_synch.c,v 1.198 2023/08/16 07:55:52 claudio Exp $ */
/* $OpenBSD: kern_synch.c,v 1.199 2023/09/08 09:06:31 claudio Exp $ */
/* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */
/*
@ -566,15 +566,18 @@ sys_sched_yield(struct proc *p, void *v, register_t *retval)
uint8_t newprio;
int s;
SCHED_LOCK(s);
/*
* If one of the threads of a multi-threaded process called
* sched_yield(2), drop its priority to ensure its siblings
* can make some progress.
*/
mtx_enter(&p->p_p->ps_mtx);
newprio = p->p_usrpri;
TAILQ_FOREACH(q, &p->p_p->ps_threads, p_thr_link)
newprio = max(newprio, q->p_runpri);
mtx_leave(&p->p_p->ps_mtx);
SCHED_LOCK(s);
setrunqueue(p->p_cpu, p, newprio);
p->p_ru.ru_nvcsw++;
mi_switch();

View file

@ -1,4 +1,4 @@
/* $OpenBSD: pf.c,v 1.1185 2023/09/07 09:59:43 sashan Exp $ */
/* $OpenBSD: pf.c,v 1.1186 2023/09/08 13:40:52 naddy Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@ -4148,10 +4148,6 @@ enter_ruleset:
(r->rule_flag & PFRULE_STATESLOPPY) == 0 &&
ctx->icmp_dir != PF_IN),
TAILQ_NEXT(r, entries));
/* icmp packet must match existing state */
PF_TEST_ATTRIB(r->keep_state && ctx->state_icmp &&
(r->rule_flag & PFRULE_STATESLOPPY) == 0,
TAILQ_NEXT(r, entries));
break;
case IPPROTO_ICMPV6:
@ -4169,10 +4165,6 @@ enter_ruleset:
ctx->icmp_dir != PF_IN &&
ctx->icmptype != ND_NEIGHBOR_ADVERT),
TAILQ_NEXT(r, entries));
/* icmp packet must match existing state */
PF_TEST_ATTRIB(r->keep_state && ctx->state_icmp &&
(r->rule_flag & PFRULE_STATESLOPPY) == 0,
TAILQ_NEXT(r, entries));
break;
default:

View file

@ -1,4 +1,4 @@
/* $OpenBSD: proc.h,v 1.349 2023/09/04 13:18:41 claudio Exp $ */
/* $OpenBSD: proc.h,v 1.350 2023/09/08 09:06:31 claudio Exp $ */
/* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */
/*-
@ -138,7 +138,7 @@ struct process {
struct ucred *ps_ucred; /* Process owner's identity. */
LIST_ENTRY(process) ps_list; /* List of all processes. */
TAILQ_HEAD(,proc) ps_threads; /* [K|S] Threads in this process. */
TAILQ_HEAD(,proc) ps_threads; /* [K|m] Threads in this process. */
LIST_ENTRY(process) ps_pglist; /* List of processes in pgrp. */
struct process *ps_pptr; /* Pointer to parent process. */
@ -310,13 +310,14 @@ struct p_inentry {
* U uidinfolk
* l read only reference, see lim_read_enter()
* o owned (read/modified only) by this thread
* m this proc's' `p->p_p->ps_mtx'
*/
struct proc {
TAILQ_ENTRY(proc) p_runq; /* [S] current run/sleep queue */
LIST_ENTRY(proc) p_list; /* List of all threads. */
struct process *p_p; /* [I] The process of this thread. */
TAILQ_ENTRY(proc) p_thr_link; /* Threads in a process linkage. */
TAILQ_ENTRY(proc) p_thr_link; /* [K|m] Threads in a process linkage. */
TAILQ_ENTRY(proc) p_fut_link; /* Threads in a futex linkage. */
struct futex *p_futex; /* Current sleeping futex. */

View file

@ -1,4 +1,4 @@
/* $OpenBSD: scp.c,v 1.257 2023/07/14 05:31:44 djm Exp $ */
/* $OpenBSD: scp.c,v 1.258 2023/09/08 05:56:13 djm Exp $ */
/*
* scp - secure remote copy. This is basically patched BSD rcp which
* uses ssh to do the data transfer (instead of using rcmd).
@ -967,7 +967,7 @@ do_sftp_connect(char *host, char *user, int port, char *sftp_direct,
reminp, remoutp, pidp) < 0)
return NULL;
}
return do_init(*reminp, *remoutp,
return sftp_init(*reminp, *remoutp,
sftp_copy_buflen, sftp_nrequests, limit_kbps);
}
@ -1263,8 +1263,8 @@ prepare_remote_path(struct sftp_conn *conn, const char *path)
return xstrdup(".");
return xstrdup(path + 2 + nslash);
}
if (can_expand_path(conn))
return do_expand_path(conn, path);
if (sftp_can_expand_path(conn))
return sftp_expand_path(conn, path);
/* No protocol extension */
error("server expand-path extension is required "
"for ~user paths in SFTP mode");
@ -1292,17 +1292,17 @@ source_sftp(int argc, char *src, char *targ, struct sftp_conn *conn)
*/
if ((target = prepare_remote_path(conn, targ)) == NULL)
cleanup_exit(255);
target_is_dir = remote_is_dir(conn, target);
target_is_dir = sftp_remote_is_dir(conn, target);
if (targetshouldbedirectory && !target_is_dir) {
debug("target directory \"%s\" does not exist", target);
a.flags = SSH2_FILEXFER_ATTR_PERMISSIONS;
a.perm = st.st_mode | 0700; /* ensure writable */
if (do_mkdir(conn, target, &a, 1) != 0)
if (sftp_mkdir(conn, target, &a, 1) != 0)
cleanup_exit(255); /* error already logged */
target_is_dir = 1;
}
if (target_is_dir)
abs_dst = path_append(target, filename);
abs_dst = sftp_path_append(target, filename);
else {
abs_dst = target;
target = NULL;
@ -1310,12 +1310,12 @@ source_sftp(int argc, char *src, char *targ, struct sftp_conn *conn)
debug3_f("copying local %s to remote %s", src, abs_dst);
if (src_is_dir && iamrecursive) {
if (upload_dir(conn, src, abs_dst, pflag,
if (sftp_upload_dir(conn, src, abs_dst, pflag,
SFTP_PROGRESS_ONLY, 0, 0, 1, 1) != 0) {
error("failed to upload directory %s to %s", src, targ);
errs = 1;
}
} else if (do_upload(conn, src, abs_dst, pflag, 0, 0, 1) != 0) {
} else if (sftp_upload(conn, src, abs_dst, pflag, 0, 0, 1) != 0) {
error("failed to upload file %s to %s", src, targ);
errs = 1;
}
@ -1524,7 +1524,7 @@ sink_sftp(int argc, char *dst, const char *src, struct sftp_conn *conn)
* a GLOB_NOCHECK result. Check whether the unglobbed path
* exists so we can give a nice error message early.
*/
if (do_stat(conn, g.gl_pathv[0], 1) == NULL) {
if (sftp_stat(conn, g.gl_pathv[0], 1, NULL) != 0) {
error("%s: %s", src, strerror(ENOENT));
err = -1;
goto out;
@ -1560,17 +1560,17 @@ sink_sftp(int argc, char *dst, const char *src, struct sftp_conn *conn)
}
if (dst_is_dir)
abs_dst = path_append(dst, filename);
abs_dst = sftp_path_append(dst, filename);
else
abs_dst = xstrdup(dst);
debug("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
if (globpath_is_dir(g.gl_pathv[i]) && iamrecursive) {
if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL,
pflag, SFTP_PROGRESS_ONLY, 0, 0, 1, 1) == -1)
if (sftp_globpath_is_dir(g.gl_pathv[i]) && iamrecursive) {
if (sftp_download_dir(conn, g.gl_pathv[i], abs_dst,
NULL, pflag, SFTP_PROGRESS_ONLY, 0, 0, 1, 1) == -1)
err = -1;
} else {
if (do_download(conn, g.gl_pathv[i], abs_dst, NULL,
if (sftp_download(conn, g.gl_pathv[i], abs_dst, NULL,
pflag, 0, 0, 1) == -1)
err = -1;
}
@ -1924,7 +1924,7 @@ throughlocal_sftp(struct sftp_conn *from, struct sftp_conn *to,
cleanup_exit(255);
memset(&g, 0, sizeof(g));
targetisdir = remote_is_dir(to, target);
targetisdir = sftp_remote_is_dir(to, target);
if (!targetisdir && targetshouldbedirectory) {
error("%s: destination is not a directory", targ);
err = -1;
@ -1949,7 +1949,7 @@ throughlocal_sftp(struct sftp_conn *from, struct sftp_conn *to,
* a GLOB_NOCHECK result. Check whether the unglobbed path
* exists so we can give a nice error message early.
*/
if (do_stat(from, g.gl_pathv[0], 1) == NULL) {
if (sftp_stat(from, g.gl_pathv[0], 1, NULL) != 0) {
error("%s: %s", src, strerror(ENOENT));
err = -1;
goto out;
@ -1965,18 +1965,18 @@ throughlocal_sftp(struct sftp_conn *from, struct sftp_conn *to,
}
if (targetisdir)
abs_dst = path_append(target, filename);
abs_dst = sftp_path_append(target, filename);
else
abs_dst = xstrdup(target);
debug("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
if (globpath_is_dir(g.gl_pathv[i]) && iamrecursive) {
if (crossload_dir(from, to, g.gl_pathv[i], abs_dst,
if (sftp_globpath_is_dir(g.gl_pathv[i]) && iamrecursive) {
if (sftp_crossload_dir(from, to, g.gl_pathv[i], abs_dst,
NULL, pflag, SFTP_PROGRESS_ONLY, 1) == -1)
err = -1;
} else {
if (do_crossload(from, to, g.gl_pathv[i], abs_dst, NULL,
pflag) == -1)
if (sftp_crossload(from, to, g.gl_pathv[i], abs_dst,
NULL, pflag) == -1)
err = -1;
}
free(abs_dst);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: servconf.c,v 1.401 2023/09/06 23:35:35 djm Exp $ */
/* $OpenBSD: servconf.c,v 1.402 2023/09/08 06:34:24 djm Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@ -1900,15 +1900,15 @@ process_server_config_line_depth(ServerOptions *options, char *line,
options->subsystem_name = xrecallocarray(
options->subsystem_name, options->num_subsystems,
options->num_subsystems + 1,
sizeof(options->subsystem_name));
sizeof(*options->subsystem_name));
options->subsystem_command = xrecallocarray(
options->subsystem_command, options->num_subsystems,
options->num_subsystems + 1,
sizeof(options->subsystem_command));
sizeof(*options->subsystem_command));
options->subsystem_args = xrecallocarray(
options->subsystem_args, options->num_subsystems,
options->num_subsystems + 1,
sizeof(options->subsystem_args));
sizeof(*options->subsystem_args));
options->subsystem_name[options->num_subsystems] = xstrdup(arg);
arg = argv_next(&ac, &av);
if (!arg || *arg == '\0') {
@ -2660,13 +2660,13 @@ servconf_merge_subsystems(ServerOptions *dst, ServerOptions *src)
debug_f("add \"%s\"", src->subsystem_name[i]);
dst->subsystem_name = xrecallocarray(
dst->subsystem_name, dst->num_subsystems,
dst->num_subsystems + 1, sizeof(dst->subsystem_name));
dst->num_subsystems + 1, sizeof(*dst->subsystem_name));
dst->subsystem_command = xrecallocarray(
dst->subsystem_command, dst->num_subsystems,
dst->num_subsystems + 1, sizeof(dst->subsystem_command));
dst->num_subsystems + 1, sizeof(*dst->subsystem_command));
dst->subsystem_args = xrecallocarray(
dst->subsystem_args, dst->num_subsystems,
dst->num_subsystems + 1, sizeof(dst->subsystem_args));
dst->num_subsystems + 1, sizeof(*dst->subsystem_args));
j = dst->num_subsystems++;
dst->subsystem_name[j] = xstrdup(src->subsystem_name[i]);
dst->subsystem_command[j] = xstrdup(src->subsystem_command[i]);

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
/* $OpenBSD: sftp-client.h,v 1.38 2022/09/19 10:43:12 djm Exp $ */
/* $OpenBSD: sftp-client.h,v 1.39 2023/09/08 05:56:13 djm Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
@ -64,107 +64,106 @@ struct sftp_limits {
* Initialise a SSH filexfer connection. Returns NULL on error or
* a pointer to a initialized sftp_conn struct on success.
*/
struct sftp_conn *do_init(int, int, u_int, u_int, u_int64_t);
struct sftp_conn *sftp_init(int, int, u_int, u_int, u_int64_t);
u_int sftp_proto_version(struct sftp_conn *);
/* Query server limits */
int do_limits(struct sftp_conn *, struct sftp_limits *);
int sftp_get_limits(struct sftp_conn *, struct sftp_limits *);
/* Close file referred to by 'handle' */
int do_close(struct sftp_conn *, const u_char *, u_int);
int sftp_close(struct sftp_conn *, const u_char *, u_int);
/* Read contents of 'path' to NULL-terminated array 'dir' */
int do_readdir(struct sftp_conn *, const char *, SFTP_DIRENT ***);
int sftp_readdir(struct sftp_conn *, const char *, SFTP_DIRENT ***);
/* Frees a NULL-terminated array of SFTP_DIRENTs (eg. from do_readdir) */
void free_sftp_dirents(SFTP_DIRENT **);
/* Frees a NULL-terminated array of SFTP_DIRENTs (eg. from sftp_readdir) */
void sftp_free_dirents(SFTP_DIRENT **);
/* Delete file 'path' */
int do_rm(struct sftp_conn *, const char *);
int sftp_rm(struct sftp_conn *, const char *);
/* Create directory 'path' */
int do_mkdir(struct sftp_conn *, const char *, Attrib *, int);
int sftp_mkdir(struct sftp_conn *, const char *, Attrib *, int);
/* Remove directory 'path' */
int do_rmdir(struct sftp_conn *, const char *);
int sftp_rmdir(struct sftp_conn *, const char *);
/* Get file attributes of 'path' (follows symlinks) */
Attrib *do_stat(struct sftp_conn *, const char *, int);
int sftp_stat(struct sftp_conn *, const char *, int, Attrib *);
/* Get file attributes of 'path' (does not follow symlinks) */
Attrib *do_lstat(struct sftp_conn *, const char *, int);
int sftp_lstat(struct sftp_conn *, const char *, int, Attrib *);
/* Set file attributes of 'path' */
int do_setstat(struct sftp_conn *, const char *, Attrib *);
int sftp_setstat(struct sftp_conn *, const char *, Attrib *);
/* Set file attributes of open file 'handle' */
int do_fsetstat(struct sftp_conn *, const u_char *, u_int, Attrib *);
int sftp_fsetstat(struct sftp_conn *, const u_char *, u_int, Attrib *);
/* Set file attributes of 'path', not following symlinks */
int do_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a);
int sftp_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a);
/* Canonicalise 'path' - caller must free result */
char *do_realpath(struct sftp_conn *, const char *);
char *sftp_realpath(struct sftp_conn *, const char *);
/* Canonicalisation with tilde expansion (requires server extension) */
char *do_expand_path(struct sftp_conn *, const char *);
char *sftp_expand_path(struct sftp_conn *, const char *);
/* Returns non-zero if server can tilde-expand paths */
int can_expand_path(struct sftp_conn *);
int sftp_can_expand_path(struct sftp_conn *);
/* Get statistics for filesystem hosting file at "path" */
int do_statvfs(struct sftp_conn *, const char *, struct sftp_statvfs *, int);
int sftp_statvfs(struct sftp_conn *, const char *, struct sftp_statvfs *, int);
/* Rename 'oldpath' to 'newpath' */
int do_rename(struct sftp_conn *, const char *, const char *, int);
int sftp_rename(struct sftp_conn *, const char *, const char *, int);
/* Copy 'oldpath' to 'newpath' */
int do_copy(struct sftp_conn *, const char *, const char *);
int sftp_copy(struct sftp_conn *, const char *, const char *);
/* Link 'oldpath' to 'newpath' */
int do_hardlink(struct sftp_conn *, const char *, const char *);
int sftp_hardlink(struct sftp_conn *, const char *, const char *);
/* Rename 'oldpath' to 'newpath' */
int do_symlink(struct sftp_conn *, const char *, const char *);
int sftp_symlink(struct sftp_conn *, const char *, const char *);
/* Call fsync() on open file 'handle' */
int do_fsync(struct sftp_conn *conn, u_char *, u_int);
int sftp_fsync(struct sftp_conn *conn, u_char *, u_int);
/*
* Download 'remote_path' to 'local_path'. Preserve permissions and times
* if 'pflag' is set
*/
int do_download(struct sftp_conn *, const char *, const char *, Attrib *,
int sftp_download(struct sftp_conn *, const char *, const char *, Attrib *,
int, int, int, int);
/*
* Recursively download 'remote_directory' to 'local_directory'. Preserve
* times if 'pflag' is set
*/
int download_dir(struct sftp_conn *, const char *, const char *, Attrib *,
int sftp_download_dir(struct sftp_conn *, const char *, const char *, Attrib *,
int, int, int, int, int, int);
/*
* Upload 'local_path' to 'remote_path'. Preserve permissions and times
* if 'pflag' is set
*/
int do_upload(struct sftp_conn *, const char *, const char *,
int sftp_upload(struct sftp_conn *, const char *, const char *,
int, int, int, int);
/*
* Recursively upload 'local_directory' to 'remote_directory'. Preserve
* times if 'pflag' is set
*/
int upload_dir(struct sftp_conn *, const char *, const char *,
int sftp_upload_dir(struct sftp_conn *, const char *, const char *,
int, int, int, int, int, int);
/*
* Download a 'from_path' from the 'from' connection and upload it to
* to 'to' connection at 'to_path'.
*/
int
do_crossload(struct sftp_conn *from, struct sftp_conn *to,
int sftp_crossload(struct sftp_conn *from, struct sftp_conn *to,
const char *from_path, const char *to_path,
Attrib *a, int preserve_flag);
@ -172,7 +171,7 @@ do_crossload(struct sftp_conn *from, struct sftp_conn *to,
* Recursively download a directory from 'from_path' from the 'from'
* connection and upload it to 'to' connection at 'to_path'.
*/
int crossload_dir(struct sftp_conn *from, struct sftp_conn *to,
int sftp_crossload_dir(struct sftp_conn *from, struct sftp_conn *to,
const char *from_path, const char *to_path,
Attrib *dirattrib, int preserve_flag, int print_flag,
int follow_link_flag);
@ -180,26 +179,23 @@ int crossload_dir(struct sftp_conn *from, struct sftp_conn *to,
/*
* User/group ID to name translation.
*/
int can_get_users_groups_by_id(struct sftp_conn *conn);
int do_get_users_groups_by_id(struct sftp_conn *conn,
int sftp_can_get_users_groups_by_id(struct sftp_conn *conn);
int sftp_get_users_groups_by_id(struct sftp_conn *conn,
const u_int *uids, u_int nuids,
const u_int *gids, u_int ngids,
char ***usernamesp, char ***groupnamesp);
/* Concatenate paths, taking care of slashes. Caller must free result. */
char *path_append(const char *, const char *);
char *sftp_path_append(const char *, const char *);
/* Make absolute path if relative path and CWD is given. Does not modify
* original if the path is already absolute. */
char *make_absolute(char *, const char *);
char *sftp_make_absolute(char *, const char *);
/* Check if remote path is directory */
int remote_is_dir(struct sftp_conn *conn, const char *path);
/* Check if local path is directory */
int local_is_dir(const char *path);
int sftp_remote_is_dir(struct sftp_conn *conn, const char *path);
/* Check whether path returned from glob(..., GLOB_MARK, ...) is a directory */
int globpath_is_dir(const char *pathname);
int sftp_globpath_is_dir(const char *pathname);
#endif

View file

@ -1,4 +1,4 @@
/* $OpenBSD: sftp-glob.c,v 1.31 2022/10/24 21:51:55 djm Exp $ */
/* $OpenBSD: sftp-glob.c,v 1.32 2023/09/08 05:56:13 djm Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
*
@ -48,7 +48,7 @@ fudge_opendir(const char *path)
r = xcalloc(1, sizeof(*r));
if (do_readdir(cur.conn, path, &r->dir)) {
if (sftp_readdir(cur.conn, path, &r->dir)) {
free(r);
return(NULL);
}
@ -76,32 +76,32 @@ fudge_readdir(struct SFTP_OPENDIR *od)
static void
fudge_closedir(struct SFTP_OPENDIR *od)
{
free_sftp_dirents(od->dir);
sftp_free_dirents(od->dir);
free(od);
}
static int
fudge_lstat(const char *path, struct stat *st)
{
Attrib *a;
Attrib a;
if (!(a = do_lstat(cur.conn, path, 1)))
return(-1);
if (sftp_lstat(cur.conn, path, 1, &a) != 0)
return -1;
attrib_to_stat(a, st);
attrib_to_stat(&a, st);
return(0);
return 0;
}
static int
fudge_stat(const char *path, struct stat *st)
{
Attrib *a;
Attrib a;
if (!(a = do_stat(cur.conn, path, 1)))
return(-1);
if (sftp_stat(cur.conn, path, 1, &a) != 0)
return -1;
attrib_to_stat(a, st);
attrib_to_stat(&a, st);
return(0);
}

View file

@ -105,9 +105,9 @@ lookup_and_record(struct sftp_conn *conn,
u_int i;
char **usernames = NULL, **groupnames = NULL;
if ((r = do_get_users_groups_by_id(conn, uids, nuids, gids, ngids,
if ((r = sftp_get_users_groups_by_id(conn, uids, nuids, gids, ngids,
&usernames, &groupnames)) != 0) {
debug_fr(r, "do_get_users_groups_by_id");
debug_fr(r, "sftp_get_users_groups_by_id");
return;
}
for (i = 0; i < nuids; i++) {
@ -175,7 +175,7 @@ get_remote_user_groups_from_glob(struct sftp_conn *conn, glob_t *g)
{
u_int *uids = NULL, nuids = 0, *gids = NULL, ngids = 0;
if (!can_get_users_groups_by_id(conn))
if (!sftp_can_get_users_groups_by_id(conn))
return;
collect_ids_from_glob(g, 1, &uids, &nuids);
@ -214,7 +214,7 @@ get_remote_user_groups_from_dirents(struct sftp_conn *conn, SFTP_DIRENT **d)
{
u_int *uids = NULL, nuids = 0, *gids = NULL, ngids = 0;
if (!can_get_users_groups_by_id(conn))
if (!sftp_can_get_users_groups_by_id(conn))
return;
collect_ids_from_dirents(d, 1, &uids, &nuids);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: sftp.c,v 1.234 2023/04/12 08:53:54 jsg Exp $ */
/* $OpenBSD: sftp.c,v 1.235 2023/09/08 05:56:13 djm Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
*
@ -607,11 +607,21 @@ make_absolute_pwd_glob(char *p, const char *pwd)
escpwd = escape_glob(pwd);
if (p == NULL)
return escpwd;
ret = make_absolute(p, escpwd);
ret = sftp_make_absolute(p, escpwd);
free(escpwd);
return ret;
}
static int
local_is_dir(const char *path)
{
struct stat sb;
if (stat(path, &sb) == -1)
return 0;
return S_ISDIR(sb.st_mode);
}
static int
process_get(struct sftp_conn *conn, const char *src, const char *dst,
const char *pwd, int pflag, int rflag, int resume, int fflag)
@ -656,12 +666,12 @@ process_get(struct sftp_conn *conn, const char *src, const char *dst,
if (g.gl_matchc == 1 && dst) {
if (local_is_dir(dst)) {
abs_dst = path_append(dst, filename);
abs_dst = sftp_path_append(dst, filename);
} else {
abs_dst = xstrdup(dst);
}
} else if (dst) {
abs_dst = path_append(dst, filename);
abs_dst = sftp_path_append(dst, filename);
} else {
abs_dst = xstrdup(filename);
}
@ -675,13 +685,14 @@ process_get(struct sftp_conn *conn, const char *src, const char *dst,
mprintf("Fetching %s to %s\n",
g.gl_pathv[i], abs_dst);
/* XXX follow link flag */
if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL,
pflag || global_pflag, 1, resume,
if (sftp_globpath_is_dir(g.gl_pathv[i]) &&
(rflag || global_rflag)) {
if (sftp_download_dir(conn, g.gl_pathv[i], abs_dst,
NULL, pflag || global_pflag, 1, resume,
fflag || global_fflag, 0, 0) == -1)
err = -1;
} else {
if (do_download(conn, g.gl_pathv[i], abs_dst, NULL,
if (sftp_download(conn, g.gl_pathv[i], abs_dst, NULL,
pflag || global_pflag, resume,
fflag || global_fflag, 0) == -1)
err = -1;
@ -710,7 +721,7 @@ process_put(struct sftp_conn *conn, const char *src, const char *dst,
if (dst) {
tmp_dst = xstrdup(dst);
tmp_dst = make_absolute(tmp_dst, pwd);
tmp_dst = sftp_make_absolute(tmp_dst, pwd);
}
memset(&g, 0, sizeof(g));
@ -723,7 +734,7 @@ process_put(struct sftp_conn *conn, const char *src, const char *dst,
/* If we aren't fetching to pwd then stash this status for later */
if (tmp_dst != NULL)
dst_is_dir = remote_is_dir(conn, tmp_dst);
dst_is_dir = sftp_remote_is_dir(conn, tmp_dst);
/* If multiple matches, dst may be directory or unspecified */
if (g.gl_matchc > 1 && tmp_dst && !dst_is_dir) {
@ -753,13 +764,13 @@ process_put(struct sftp_conn *conn, const char *src, const char *dst,
if (g.gl_matchc == 1 && tmp_dst) {
/* If directory specified, append filename */
if (dst_is_dir)
abs_dst = path_append(tmp_dst, filename);
abs_dst = sftp_path_append(tmp_dst, filename);
else
abs_dst = xstrdup(tmp_dst);
} else if (tmp_dst) {
abs_dst = path_append(tmp_dst, filename);
abs_dst = sftp_path_append(tmp_dst, filename);
} else {
abs_dst = make_absolute(xstrdup(filename), pwd);
abs_dst = sftp_make_absolute(xstrdup(filename), pwd);
}
free(tmp);
@ -771,13 +782,14 @@ process_put(struct sftp_conn *conn, const char *src, const char *dst,
mprintf("Uploading %s to %s\n",
g.gl_pathv[i], abs_dst);
/* XXX follow_link_flag */
if (globpath_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
if (upload_dir(conn, g.gl_pathv[i], abs_dst,
if (sftp_globpath_is_dir(g.gl_pathv[i]) &&
(rflag || global_rflag)) {
if (sftp_upload_dir(conn, g.gl_pathv[i], abs_dst,
pflag || global_pflag, 1, resume,
fflag || global_fflag, 0, 0) == -1)
err = -1;
} else {
if (do_upload(conn, g.gl_pathv[i], abs_dst,
if (sftp_upload(conn, g.gl_pathv[i], abs_dst,
pflag || global_pflag, resume,
fflag || global_fflag, 0) == -1)
err = -1;
@ -818,7 +830,7 @@ do_ls_dir(struct sftp_conn *conn, const char *path,
u_int c = 1, colspace = 0, columns = 1;
SFTP_DIRENT **d;
if ((n = do_readdir(conn, path, &d)) != 0)
if ((n = sftp_readdir(conn, path, &d)) != 0)
return (n);
if (!(lflag & LS_SHORT_VIEW)) {
@ -860,13 +872,13 @@ do_ls_dir(struct sftp_conn *conn, const char *path,
if (d[n]->filename[0] == '.' && !(lflag & LS_SHOW_ALL))
continue;
tmp = path_append(path, d[n]->filename);
tmp = sftp_path_append(path, d[n]->filename);
fname = path_strip(tmp, strip_path);
free(tmp);
if (lflag & LS_LONG_VIEW) {
if ((lflag & (LS_NUMERIC_VIEW|LS_SI_UNITS)) != 0 ||
can_get_users_groups_by_id(conn)) {
sftp_can_get_users_groups_by_id(conn)) {
char *lname;
struct stat sb;
@ -895,7 +907,7 @@ do_ls_dir(struct sftp_conn *conn, const char *path,
if (!(lflag & LS_LONG_VIEW) && (c != 1))
printf("\n");
free_sftp_dirents(d);
sftp_free_dirents(d);
return (0);
}
@ -1043,7 +1055,7 @@ do_df(struct sftp_conn *conn, const char *path, int hflag, int iflag)
char s_root[FMT_SCALED_STRSIZE], s_total[FMT_SCALED_STRSIZE];
char s_icapacity[16], s_dcapacity[16];
if (do_statvfs(conn, path, &st, 1) == -1)
if (sftp_statvfs(conn, path, &st, 1) == -1)
return -1;
if (st.f_files == 0)
strlcpy(s_icapacity, "ERR", sizeof(s_icapacity));
@ -1517,7 +1529,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
int lflag = 0, pflag = 0, rflag = 0, sflag = 0;
int cmdnum, i;
unsigned long n_arg = 0;
Attrib a, *aa;
Attrib a, aa;
char path_buf[PATH_MAX];
int err = 0;
glob_t g;
@ -1558,23 +1570,24 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
rflag, aflag, fflag);
break;
case I_COPY:
path1 = make_absolute(path1, *pwd);
path2 = make_absolute(path2, *pwd);
err = do_copy(conn, path1, path2);
path1 = sftp_make_absolute(path1, *pwd);
path2 = sftp_make_absolute(path2, *pwd);
err = sftp_copy(conn, path1, path2);
break;
case I_RENAME:
path1 = make_absolute(path1, *pwd);
path2 = make_absolute(path2, *pwd);
err = do_rename(conn, path1, path2, lflag);
path1 = sftp_make_absolute(path1, *pwd);
path2 = sftp_make_absolute(path2, *pwd);
err = sftp_rename(conn, path1, path2, lflag);
break;
case I_SYMLINK:
sflag = 1;
/* FALLTHROUGH */
case I_LINK:
if (!sflag)
path1 = make_absolute(path1, *pwd);
path2 = make_absolute(path2, *pwd);
err = (sflag ? do_symlink : do_hardlink)(conn, path1, path2);
path1 = sftp_make_absolute(path1, *pwd);
path2 = sftp_make_absolute(path2, *pwd);
err = (sflag ? sftp_symlink : sftp_hardlink)(conn,
path1, path2);
break;
case I_RM:
path1 = make_absolute_pwd_glob(path1, *pwd);
@ -1582,42 +1595,42 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
if (!quiet)
mprintf("Removing %s\n", g.gl_pathv[i]);
err = do_rm(conn, g.gl_pathv[i]);
err = sftp_rm(conn, g.gl_pathv[i]);
if (err != 0 && err_abort)
break;
}
break;
case I_MKDIR:
path1 = make_absolute(path1, *pwd);
path1 = sftp_make_absolute(path1, *pwd);
attrib_clear(&a);
a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
a.perm = 0777;
err = do_mkdir(conn, path1, &a, 1);
err = sftp_mkdir(conn, path1, &a, 1);
break;
case I_RMDIR:
path1 = make_absolute(path1, *pwd);
err = do_rmdir(conn, path1);
path1 = sftp_make_absolute(path1, *pwd);
err = sftp_rmdir(conn, path1);
break;
case I_CHDIR:
if (path1 == NULL || *path1 == '\0')
path1 = xstrdup(startdir);
path1 = make_absolute(path1, *pwd);
if ((tmp = do_realpath(conn, path1)) == NULL) {
path1 = sftp_make_absolute(path1, *pwd);
if ((tmp = sftp_realpath(conn, path1)) == NULL) {
err = 1;
break;
}
if ((aa = do_stat(conn, tmp, 0)) == NULL) {
if (sftp_stat(conn, tmp, 0, &aa) != 0) {
free(tmp);
err = 1;
break;
}
if (!(aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) {
if (!(aa.flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) {
error("Can't change directory: Can't check target");
free(tmp);
err = 1;
break;
}
if (!S_ISDIR(aa->perm)) {
if (!S_ISDIR(aa.perm)) {
error("Can't change directory: \"%s\" is not "
"a directory", tmp);
free(tmp);
@ -1645,7 +1658,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
/* Default to current directory if no path specified */
if (path1 == NULL)
path1 = xstrdup(*pwd);
path1 = make_absolute(path1, *pwd);
path1 = sftp_make_absolute(path1, *pwd);
err = do_df(conn, path1, hflag, iflag);
break;
case I_LCHDIR:
@ -1687,7 +1700,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
if (!quiet)
mprintf("Changing mode on %s\n",
g.gl_pathv[i]);
err = (hflag ? do_lsetstat : do_setstat)(conn,
err = (hflag ? sftp_lsetstat : sftp_setstat)(conn,
g.gl_pathv[i], &a);
if (err != 0 && err_abort)
break;
@ -1698,15 +1711,15 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
path1 = make_absolute_pwd_glob(path1, *pwd);
remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
if (!(aa = (hflag ? do_lstat : do_stat)(conn,
g.gl_pathv[i], 0))) {
if ((hflag ? sftp_lstat : sftp_stat)(conn,
g.gl_pathv[i], 0, &aa) != 0) {
if (err_abort) {
err = -1;
break;
} else
continue;
}
if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
if (!(aa.flags & SSH2_FILEXFER_ATTR_UIDGID)) {
error("Can't get current ownership of "
"remote file \"%s\"", g.gl_pathv[i]);
if (err_abort) {
@ -1715,20 +1728,20 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
} else
continue;
}
aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
aa.flags &= SSH2_FILEXFER_ATTR_UIDGID;
if (cmdnum == I_CHOWN) {
if (!quiet)
mprintf("Changing owner on %s\n",
g.gl_pathv[i]);
aa->uid = n_arg;
aa.uid = n_arg;
} else {
if (!quiet)
mprintf("Changing group on %s\n",
g.gl_pathv[i]);
aa->gid = n_arg;
aa.gid = n_arg;
}
err = (hflag ? do_lsetstat : do_setstat)(conn,
g.gl_pathv[i], aa);
err = (hflag ? sftp_lsetstat : sftp_setstat)(conn,
g.gl_pathv[i], &aa);
if (err != 0 && err_abort)
break;
}
@ -2203,16 +2216,15 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2)
el_set(el, EL_BIND, "^w", "ed-delete-prev-word", NULL);
}
remote_path = do_realpath(conn, ".");
if (remote_path == NULL)
if ((remote_path = sftp_realpath(conn, ".")) == NULL)
fatal("Need cwd");
startdir = xstrdup(remote_path);
if (file1 != NULL) {
dir = xstrdup(file1);
dir = make_absolute(dir, remote_path);
dir = sftp_make_absolute(dir, remote_path);
if (remote_is_dir(conn, dir) && file2 == NULL) {
if (sftp_remote_is_dir(conn, dir) && file2 == NULL) {
if (!quiet)
mprintf("Changing to: %s\n", dir);
snprintf(cmd, sizeof cmd, "cd \"%s\"", dir);
@ -2603,7 +2615,7 @@ main(int argc, char **argv)
}
freeargs(&args);
conn = do_init(in, out, copy_buffer_len, num_requests, limit_kbps);
conn = sftp_init(in, out, copy_buffer_len, num_requests, limit_kbps);
if (conn == NULL)
fatal("Couldn't initialise connection to server");

View file

@ -1,4 +1,4 @@
/* $OpenBSD: format.c,v 1.317 2023/08/17 14:10:28 nicm Exp $ */
/* $OpenBSD: format.c,v 1.318 2023/09/08 06:52:31 nicm Exp $ */
/*
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
@ -1126,7 +1126,6 @@ format_cb_mouse_word(struct format_tree *ft)
struct window_pane *wp;
struct grid *gd;
u_int x, y;
char *s;
if (!ft->m.valid)
return (NULL);
@ -1139,7 +1138,7 @@ format_cb_mouse_word(struct format_tree *ft)
if (!TAILQ_EMPTY(&wp->modes)) {
if (TAILQ_FIRST(&wp->modes)->mode == &window_copy_mode ||
TAILQ_FIRST(&wp->modes)->mode == &window_view_mode)
return (s = window_copy_get_word(wp, x, y));
return (window_copy_get_word(wp, x, y));
return (NULL);
}
gd = wp->base.grid;
@ -4185,7 +4184,7 @@ static char *
format_loop_clients(struct format_expand_state *es, const char *fmt)
{
struct format_tree *ft = es->ft;
struct client *c = ft->client;
struct client *c;
struct cmdq_item *item = ft->item;
struct format_tree *nft;
struct format_expand_state next;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: tty-keys.c,v 1.170 2023/09/07 10:21:46 nicm Exp $ */
/* $OpenBSD: tty-keys.c,v 1.172 2023/09/08 07:05:06 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@ -1315,15 +1315,21 @@ tty_keys_device_attributes(struct tty *tty, const char *buf, size_t len,
}
/*
* Add terminal features. Technically, VT420 and VT525 do not support
* SIXEL, but some modern terminals report it anyway so we accept it
* here too.
* Add terminal features. Hardware level 5 does not offer SIXEL but
* some terminal emulators report it anyway and it does not harm
* to check it here.
*
* DECSLRM and DECFRA should be supported by level 5 as well as level
* 4, but VTE has rather ruined it by advertising level 5 despite not
* supporting them.
*/
switch (p[0]) {
case 62: /* VT220 */
case 63: /* VT320 */
case 64: /* VT420 */
case 65: /* VT525 */
case 64: /* level 4 */
tty_add_features(features, "margins,rectfill", ",");
/* FALLTHROUGH */
case 62: /* level 2 */
case 63: /* level 3 */
case 65: /* level 5 */
for (i = 1; i < n; i++) {
log_debug("%s: DA feature: %d", c->name, p[i]);
if (p[i] == 4)
@ -1393,12 +1399,15 @@ tty_keys_device_attributes2(struct tty *tty, const char *buf, size_t len,
break;
}
/* Add terminal features. */
/*
* Add terminal features. We add DECSLRM and DECFRA for some
* identification codes here, notably 64 will catch VT520, even though
* we can't use level 5 from DA because of VTE.
*/
switch (p[0]) {
case 41: /* VT420 */
case 61: /* VT510 */
case 64: /* VT520 */
case 65: /* VT525 */
tty_add_features(features, "margins,rectfill", ",");
break;
case 'M': /* mintty */

View file

@ -1,6 +1,7 @@
# $OpenBSD: Makefile,v 1.1 2015/07/21 04:06:04 yasuoka Exp $
# $OpenBSD: Makefile,v 1.2 2023/09/08 05:56:22 yasuoka Exp $
SUBDIR= radiusd
SUBDIR+= radiusd_bsdauth
SUBDIR+= radiusd_radius
SUBDIR+= radiusd_standard
.include <bsd.prog.mk>

View file

@ -1,4 +1,4 @@
/* $OpenBSD: parse.y,v 1.16 2023/09/05 00:32:01 yasuoka Exp $ */
/* $OpenBSD: parse.y,v 1.17 2023/09/08 05:56:22 yasuoka Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -349,7 +349,6 @@ authopt : AUTHENTICATE_BY STRING {
YYERROR;
authen.auth = modref;
}
/* XXX decoration doesn't work for this moment. */
| DECORATE_BY str_l {
int i;
struct radiusd_module_ref *modref;

View file

@ -1,7 +1,7 @@
/* $OpenBSD: radiusd.c,v 1.31 2023/09/05 00:32:01 yasuoka Exp $ */
/* $OpenBSD: radiusd.c,v 1.32 2023/09/08 05:56:22 yasuoka Exp $ */
/*
* Copyright (c) 2013 Internet Initiative Japan Inc.
* Copyright (c) 2013, 2023 Internet Initiative Japan Inc.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -17,13 +17,14 @@
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/queue.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/uio.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <dlfcn.h>
#include <err.h>
#include <errno.h>
#include <event.h>
@ -40,7 +41,6 @@
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include <util.h>
#include <radius.h>
@ -58,9 +58,8 @@ static void radiusd_on_sigterm(int, short, void *);
static void radiusd_on_sigint(int, short, void *);
static void radiusd_on_sighup(int, short, void *);
static void radiusd_on_sigchld(int, short, void *);
static int radius_query_request_decoration(struct radius_query *);
static int radius_query_response_decoration(
struct radius_query *);
static void radius_query_request(struct radius_query *);
static void radius_query_response(struct radius_query *);
static const char *radius_code_string(int);
static int radiusd_access_response_fixup (struct radius_query *);
@ -84,6 +83,12 @@ static void radiusd_module_userpass(struct radiusd_module *,
struct radius_query *);
static void radiusd_module_access_request(struct radiusd_module *,
struct radius_query *);
static void radiusd_module_request_decoration(
struct radiusd_module *, struct radius_query *);
static void radiusd_module_response_decoration(
struct radiusd_module *, struct radius_query *);
static int imsg_compose_radius_packet(struct imsgbuf *,
uint32_t, u_int, RADIUS_PACKET *);
static u_int radius_query_id_seq = 0;
int debug = 0;
@ -482,6 +487,7 @@ radiusd_listen_on_event(int fd, short evmask, void *ctx)
goto found;
}
}
found:
if (authen == NULL) {
log_warnx("Received %s(code=%d) from %s id=%d "
"username=%s: no `authenticate' matches.",
@ -489,7 +495,6 @@ radiusd_listen_on_event(int fd, short evmask, void *ctx)
req_id, username);
goto on_error;
}
found:
RADIUSD_ASSERT(authen->auth != NULL);
if (!MODULE_DO_USERPASS(authen->auth->module) &&
@ -515,25 +520,13 @@ found:
q->req_id = req_id;
radius_get_authenticator(packet, q->req_auth);
if (radius_query_request_decoration(q) != 0) {
log_warnx(
"Received %s(code=%d) from %s id=%d username=%s "
"q=%u: failed to decorate the request",
radius_code_string(req_code), req_code, peerstr,
q->req_id, q->username, q->id);
radiusd_access_request_aborted(q);
return;
}
log_info("Received %s(code=%d) from %s id=%d username=%s "
"q=%u: `%s' authentication is starting",
radius_code_string(req_code), req_code, peerstr, q->req_id,
q->username, q->id, q->authen->auth->module->name);
TAILQ_INSERT_TAIL(&listn->radiusd->query, q, next);
if (MODULE_DO_ACCSREQ(authen->auth->module)) {
radiusd_module_access_request(authen->auth->module, q);
} else if (MODULE_DO_USERPASS(authen->auth->module))
radiusd_module_userpass(authen->auth->module, q);
radius_query_request(q);
return;
}
@ -546,77 +539,52 @@ on_error:
return;
}
static int
radius_query_request_decoration(struct radius_query *q)
static void
radius_query_request(struct radius_query *q)
{
struct radiusd_module_ref *deco;
struct radiusd_authentication *authen = q->authen;
TAILQ_FOREACH(deco, &q->authen->deco, next) {
/* XXX decoration doesn't work for this moment. */
if (deco->module->request_decoration != NULL &&
deco->module->request_decoration(NULL, q) != 0) {
log_warnx("q=%u request decoration `%s' failed", q->id,
deco->module->name);
return (-1);
}
/* first or next request decoration */
for (;;) {
if (q->deco == NULL)
q->deco = TAILQ_FIRST(&q->authen->deco);
else
q->deco = TAILQ_NEXT(q->deco, next);
if (q->deco == NULL || MODULE_DO_REQDECO(q->deco->module))
break;
}
return (0);
}
static int
radius_query_response_decoration(struct radius_query *q)
{
struct radiusd_module_ref *deco;
TAILQ_FOREACH(deco, &q->authen->deco, next) {
/* XXX decoration doesn't work for this moment. */
if (deco->module->response_decoration != NULL &&
deco->module->response_decoration(NULL, q) != 0) {
log_warnx("q=%u response decoration `%s' failed", q->id,
deco->module->name);
return (-1);
}
if (q->deco != NULL)
radiusd_module_request_decoration(q->deco->module, q);
else {
RADIUSD_ASSERT(authen->auth != NULL);
if (MODULE_DO_ACCSREQ(authen->auth->module))
radiusd_module_access_request(authen->auth->module, q);
else if (MODULE_DO_USERPASS(authen->auth->module))
radiusd_module_userpass(authen->auth->module, q);
}
return (0);
}
/***********************************************************************
* Callback functions from the modules
***********************************************************************/
void
radiusd_access_request_answer(struct radius_query *q)
static void
radius_query_response(struct radius_query *q)
{
int sz, res_id, res_code;
char buf[NI_MAXHOST + NI_MAXSERV + 30];
const char *authen_secret = q->authen->auth->module->secret;
radius_set_request_packet(q->res, q->req);
if (authen_secret == NULL) {
/*
* The module couldn't check the authenticators
*/
if (radius_check_response_authenticator(q->res,
q->client->secret) != 0) {
log_info("Response from module has bad response "
"authenticator: id=%d", q->id);
goto on_error;
}
if (radius_has_attr(q->res,
RADIUS_TYPE_MESSAGE_AUTHENTICATOR) &&
radius_check_message_authenticator(q->res,
q->client->secret) != 0) {
log_info("Response from module has bad message "
"authenticator: id=%d", q->id);
goto on_error;
}
/* first or next response decoration */
for (;;) {
if (q->deco == NULL)
q->deco = TAILQ_FIRST(&q->authen->deco);
else
q->deco = TAILQ_NEXT(q->deco, next);
if (q->deco == NULL || MODULE_DO_RESDECO(q->deco->module))
break;
}
/* Decorate the response */
if (radius_query_response_decoration(q) != 0)
goto on_error;
if (q->deco != NULL) {
radiusd_module_response_decoration(q->deco->module, q);
return;
}
if (radiusd_access_response_fixup(q) != 0)
goto on_error;
@ -641,6 +609,45 @@ radiusd_access_request_answer(struct radius_query *q)
log_warn("Sending a RADIUS response failed");
on_error:
radiusd_access_request_aborted(q);
}
/***********************************************************************
* Callback functions from the modules
***********************************************************************/
void
radiusd_access_request_answer(struct radius_query *q)
{
const char *authen_secret = q->authen->auth->module->secret;
radius_set_request_packet(q->res, q->req);
if (authen_secret == NULL) {
/*
* The module diddn't check the authenticators
*/
if (radius_check_response_authenticator(q->res,
q->client->secret) != 0) {
log_info("Response from module has bad response "
"authenticator: id=%d", q->id);
goto on_error;
}
if (radius_has_attr(q->res,
RADIUS_TYPE_MESSAGE_AUTHENTICATOR) &&
radius_check_message_authenticator(q->res,
q->client->secret) != 0) {
log_info("Response from module has bad message "
"authenticator: id=%d", q->id);
goto on_error;
}
}
RADIUSD_ASSERT(q->deco == NULL);
radius_query_response(q);
return;
on_error:
radiusd_access_request_aborted(q);
}
void
@ -754,23 +761,6 @@ radiusd_conf_init(struct radiusd *conf)
TAILQ_INIT(&conf->authen);
TAILQ_INIT(&conf->client);
/*
* TODO: load the standard modules
*/
#if 0
static struct radiusd_module *radiusd_standard_modules[] = {
NULL
};
u_int i;
struct radiusd_module *module;
for (i = 0; radiusd_standard_modules[i] != NULL; i++) {
module = radiusd_create_module_class(
radiusd_standard_modules[i]);
TAILQ_INSERT_TAIL(&conf->module, module, next);
}
#endif
return;
}
@ -793,6 +783,9 @@ radiusd_access_response_fixup(struct radius_query *q)
const char *olds = q->client->secret;
const char *news = authen_secret;
if (news == NULL)
news = olds;
/* RFC 2865 Tunnel-Password */
attrlen = sizeof(attrlen);
if (radius_get_raw_attr(q->res, RADIUS_TYPE_TUNNEL_PASSWORD,
@ -1238,28 +1231,77 @@ radiusd_module_imsg(struct radiusd_module *module, struct imsg *imsg)
break;
}
case IMSG_RADIUSD_MODULE_ACCSREQ_ANSWER:
case IMSG_RADIUSD_MODULE_REQDECO_DONE:
case IMSG_RADIUSD_MODULE_RESDECO_DONE:
{
static struct radiusd_module_radpkt_arg *ans;
const char *typestr = "unknown";
switch (imsg->hdr.type) {
case IMSG_RADIUSD_MODULE_ACCSREQ_ANSWER:
typestr = "ACCSREQ_ANSWER";
break;
case IMSG_RADIUSD_MODULE_REQDECO_DONE:
typestr = "REQDECO_DONE";
break;
case IMSG_RADIUSD_MODULE_RESDECO_DONE:
typestr = "RESDECO_DONE";
break;
}
if (datalen <
(ssize_t)sizeof(struct radiusd_module_radpkt_arg)) {
log_warnx("Received ACCSREQ_ANSWER message, but "
"length is wrong");
log_warnx("Received %s message, but length is wrong",
typestr);
break;
}
q_id = ((struct radiusd_module_radpkt_arg *)imsg->data)->q_id;
q = radiusd_find_query(module->radiusd, q_id);
if (q == NULL) {
log_warnx("Received ACCSREQ_ANSWER from %s, but query "
"id=%u unknown", module->name, q_id);
log_warnx("Received %s from %s, but query id=%u "
"unknown", typestr, module->name, q_id);
break;
}
if ((ans = radiusd_module_recv_radpkt(module, imsg,
IMSG_RADIUSD_MODULE_ACCSREQ_ANSWER,
"ACCSREQ_ANSWER")) != NULL) {
q->res = radius_convert_packet(
module->radpkt, module->radpktoff);
radiusd_access_request_answer(q);
imsg->hdr.type, typestr)) != NULL) {
RADIUS_PACKET *radpkt = NULL;
if (module->radpktoff > 0 &&
(radpkt = radius_convert_packet(
module->radpkt, module->radpktoff)) == NULL) {
log_warn("q=%u radius_convert_packet() failed",
q->id);
radiusd_access_request_aborted(q);
break;
}
module->radpktoff = 0;
switch (imsg->hdr.type) {
case IMSG_RADIUSD_MODULE_REQDECO_DONE:
if (radpkt != NULL) {
radius_delete_packet(q->req);
q->req = radpkt;
}
radius_query_request(q);
break;
case IMSG_RADIUSD_MODULE_ACCSREQ_ANSWER:
if (radpkt == NULL) {
log_warn("q=%u wrong pkt from module",
q->id);
radiusd_access_request_aborted(q);
}
q->res = radpkt;
radiusd_access_request_answer(q);
break;
case IMSG_RADIUSD_MODULE_RESDECO_DONE:
if (radpkt != NULL) {
radius_delete_packet(q->res);
radius_set_request_packet(radpkt,
q->req);
q->res = radpkt;
}
radius_query_response(q);
break;
}
}
break;
}
@ -1276,8 +1318,8 @@ radiusd_module_imsg(struct radiusd_module *module, struct imsg *imsg)
break;
}
default:
RADIUSD_DBG(("Unhandled imsg type=%d",
imsg->hdr.type));
RADIUSD_DBG(("Unhandled imsg type=%d from %s", imsg->hdr.type,
module->name));
}
}
@ -1306,9 +1348,11 @@ radiusd_module_recv_radpkt(struct radiusd_module *module, struct imsg *imsg,
"received length is too big", type_str, module->name);
goto on_fail;
}
memcpy(module->radpkt + module->radpktoff,
(caddr_t)(ans + 1), chunklen);
module->radpktoff += chunklen;
if (chunklen > 0) {
memcpy(module->radpkt + module->radpktoff,
(caddr_t)(ans + 1), chunklen);
module->radpktoff += chunklen;
}
if (!ans->final)
return (NULL); /* again */
if (module->radpktoff != ans->pktlen) {
@ -1427,11 +1471,9 @@ radiusd_module_userpass(struct radiusd_module *module, struct radius_query *q)
userpass.has_pass = true;
else
userpass.has_pass = false;
if (strlcpy(userpass.user, q->username, sizeof(userpass.user))
>= sizeof(userpass.user)) {
log_warnx("Could request USERPASS to module `%s': "
"User-Name too long", module->name);
if (radius_get_string_attr(q->req, RADIUS_TYPE_USER_NAME,
userpass.user, sizeof(userpass.user)) != 0) {
log_warnx("q=%u no User-Name attribute", q->id);
goto on_error;
}
imsg_compose(&module->ibuf, IMSG_RADIUSD_MODULE_USERPASS, 0, 0, -1,
@ -1446,16 +1488,14 @@ static void
radiusd_module_access_request(struct radiusd_module *module,
struct radius_query *q)
{
struct radiusd_module_radpkt_arg accsreq;
struct iovec iov[2];
int off = 0, len, siz;
const u_char *pkt;
RADIUS_PACKET *radpkt;
char pass[256];
if ((radpkt = radius_convert_packet(radius_get_data(q->req),
radius_get_length(q->req))) == NULL) {
log_warn("Could not send ACCSREQ for `%s'", module->name);
log_warn("q=%u Could not send ACCSREQ to `%s'", q->id,
module->name);
radiusd_access_request_aborted(q);
return;
}
if (q->client->secret[0] != '\0' && module->secret != NULL &&
@ -1465,30 +1505,85 @@ radiusd_module_access_request(struct radiusd_module *module,
(void)radius_put_raw_attr(radpkt, RADIUS_TYPE_USER_PASSWORD,
pass, strlen(pass));
}
pkt = radius_get_data(radpkt);
len = radius_get_length(radpkt);
memset(&accsreq, 0, sizeof(accsreq));
accsreq.q_id = q->id;
accsreq.pktlen = len;
while (off < len) {
siz = MAX_IMSGSIZE - sizeof(accsreq);
if (len - off > siz)
accsreq.final = false;
else {
accsreq.final = true;
siz = len - off;
}
iov[0].iov_base = &accsreq;
iov[0].iov_len = sizeof(accsreq);
iov[1].iov_base = (caddr_t)pkt + off;
iov[1].iov_len = siz;
imsg_composev(&module->ibuf, IMSG_RADIUSD_MODULE_ACCSREQ, 0, 0,
-1, iov, 2);
off += siz;
if (imsg_compose_radius_packet(&module->ibuf,
IMSG_RADIUSD_MODULE_ACCSREQ, q->id, radpkt) == -1) {
log_warn("q=%u Could not send ACCSREQ to `%s'", q->id,
module->name);
radiusd_access_request_aborted(q);
}
radiusd_module_reset_ev_handler(module);
radius_delete_packet(radpkt);
return;
}
static void
radiusd_module_request_decoration(struct radiusd_module *module,
struct radius_query *q)
{
if (module->fd < 0) {
log_warnx("q=%u Could not send REQDECO to `%s': module is "
"not running?", q->id, module->name);
radiusd_access_request_aborted(q);
return;
}
if (imsg_compose_radius_packet(&module->ibuf,
IMSG_RADIUSD_MODULE_REQDECO, q->id, q->req) == -1) {
log_warn("q=%u Could not send REQDECO to `%s'", q->id,
module->name);
radiusd_access_request_aborted(q);
return;
}
radiusd_module_reset_ev_handler(module);
}
static void
radiusd_module_response_decoration(struct radiusd_module *module,
struct radius_query *q)
{
if (module->fd < 0) {
log_warnx("q=%u Could not send RESDECO to `%s': module is "
"not running?", q->id, module->name);
radiusd_access_request_aborted(q);
return;
}
if (imsg_compose_radius_packet(&module->ibuf,
IMSG_RADIUSD_MODULE_RESDECO, q->id, q->res) == -1) {
log_warn("q=%u Could not send RESDECO to `%s'", q->id,
module->name);
radiusd_access_request_aborted(q);
return;
}
radiusd_module_reset_ev_handler(module);
}
static int
imsg_compose_radius_packet(struct imsgbuf *ibuf, uint32_t type, u_int q_id,
RADIUS_PACKET *radpkt)
{
struct radiusd_module_radpkt_arg arg;
int off = 0, len, siz;
struct iovec iov[2];
const u_char *pkt;
pkt = radius_get_data(radpkt);
len = radius_get_length(radpkt);
memset(&arg, 0, sizeof(arg));
arg.q_id = q_id;
arg.pktlen = len;
while (off < len) {
siz = MAX_IMSGSIZE - sizeof(arg);
if (len - off > siz)
arg.final = false;
else {
arg.final = true;
siz = len - off;
}
iov[0].iov_base = &arg;
iov[0].iov_len = sizeof(arg);
iov[1].iov_base = (caddr_t)pkt + off;
iov[1].iov_len = siz;
if (imsg_composev(ibuf, type, 0, 0, -1, iov, 2) == -1)
return (-1);
off += siz;
}
return (0);
}

View file

@ -1,7 +1,7 @@
.\" $OpenBSD: radiusd.conf.5,v 1.16 2023/09/04 12:28:18 yasuoka Exp $
.\" $OpenBSD: radiusd.conf.5,v 1.17 2023/09/08 05:56:22 yasuoka Exp $
.\"
.\" Copyright (c) 2014 Esdenera Networks GmbH
.\" Copyright (c) 2014 Internet Initiative Japan Inc.
.\" Copyright (c) 2014, 2023 Internet Initiative Japan Inc.
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
@ -15,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd $Mdocdate: September 4 2023 $
.Dd $Mdocdate: September 8 2023 $
.Dt RADIUSD.CONF 5
.Os
.Sh NAME
@ -68,6 +68,7 @@ The following modules are available:
.It Sy "Path" Ta Sy "Description"
.It Pa /usr/libexec/radiusd/radiusd_bsdauth Ta Do bsdauth Dc module
.It Pa /usr/libexec/radiusd/radiusd_radius Ta Do radius Dc module
.It Pa /usr/libexec/radiusd/radiusd_standard Ta Do standard Dc module
.El
.Bl -tag -width Ds
.It Do bsdauth Dc module
@ -83,6 +84,11 @@ It only supports PAP, password based authentication.
The
.Dq radius
module provides authentication from upstream RADIUS servers.
.It Do standard Dc module
The
.Dq standard
module provides standard decorations for Access-Request messages or its
response messages.
.El
.It Ic module set Ar module key value ...
Configure the module specific configurations by
@ -146,6 +152,34 @@ and
.Ar max-failover
will not be used.
.El
.Pp
The
.Dq standard
module supports the following configuration key and value:
.Pp
.Bl -tag -width Ds -offset indent -compact
.It Ic strip-atmark-realm Ar true | false
Remove the realm part which starts with @
.Pq atmark
from the User-Name attribute of the Access-Request.
.Pp
.It Ic strip-nt-domain Ar true | false
Remove NT domain which ends with \\
.Pq backslash
from the User-Name attribute of the Access-Request.
.Pp
.It Cm remove-request-attribute Oo Ar vendor Oc Ar type
.It Cm remove-response-attribute Oo Ar vendor Oc Ar type
Remove all the specified attributes from request or response
messages of Access-Request.
Specify
.Ar type
of the attribute in a decimal number.
To specify a vendor attribute,
specify the Vendor-Id
in a decimal number for
.Ar vendor .
.El
.It Ic authenticate Ar username-pattern ... Brq ...
Specify an authentication configuration for the users specified by
.Ar username-pattern .
@ -162,6 +196,8 @@ It is followed by a block of options enclosed in curly brackets:
.Bl -tag -width Ds
.It Ic authenticate-by Ar module
Specify the module name.
.It Ic decorate-by Ar module
Specify the module name.
.El
.El
.Sh FILES
@ -182,28 +218,32 @@ module executable.
.Sh EXAMPLES
.Bd -literal -offset indent
listen on 0.0.0.0
#listen on ::
listen on ::
client 127.0.0.1/32 {
secret "secret"
msgauth-required no
}
client 192.168.0.0/24 {
secret "secret"
msgauth-required yes
}
module load bsdauth "/usr/libexec/radiusd/radiusd_bsdauth"
module set bsdauth restrict-group "operator"
module set bsdauth restrict-group operator
module load radius "/usr/libexec/radiusd/radiusd_radius"
module set radius secret "testing123"
module set radius server "127.0.0.1"
authenticate *@example.com {
authenticate-by radius
module load strip-realm "/usr/libexec/radiusd/radiusd_standard"
module set strip-realm strip-atmark-realm true
authenticate *@local {
authenticate-by bsdauth
decorate-by strip-realm
}
authenticate * {
authenticate-by bsdauth
authenticate-by radius
}
.Ed
.Sh SEE ALSO

View file

@ -1,4 +1,4 @@
/* $OpenBSD: radiusd.h,v 1.4 2019/04/03 11:54:56 yasuoka Exp $ */
/* $OpenBSD: radiusd.h,v 1.5 2023/09/08 05:56:22 yasuoka Exp $ */
#ifndef RADIUSD_H
#define RADIUSD_H 1
@ -17,6 +17,8 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <stdint.h>
#include <stdbool.h>
#define RADIUSD_MODULE_NAME_LEN 32
@ -38,6 +40,10 @@ enum imsg_type {
/* Check the response's authenticator if the module doesn't */
IMSG_RADIUSD_MODULE_ACCSREQ_ANSWER,
IMSG_RADIUSD_MODULE_ACCSREQ_ABORTED,
IMSG_RADIUSD_MODULE_REQDECO,
IMSG_RADIUSD_MODULE_REQDECO_DONE,
IMSG_RADIUSD_MODULE_RESDECO,
IMSG_RADIUSD_MODULE_RESDECO_DONE,
IMSG_RADIUSD_MODULE_STOP
};
@ -46,6 +52,8 @@ struct radiusd_module_load_arg {
uint32_t cap; /* module capabity bits */
#define RADIUSD_MODULE_CAP_USERPASS 0x1
#define RADIUSD_MODULE_CAP_ACCSREQ 0x2
#define RADIUSD_MODULE_CAP_REQDECO 0x4
#define RADIUSD_MODULE_CAP_RESDECO 0x8
};
struct radiusd_module_object {

View file

@ -1,4 +1,4 @@
/* $OpenBSD: radiusd_local.h,v 1.5 2019/04/01 11:05:41 yasuoka Exp $ */
/* $OpenBSD: radiusd_local.h,v 1.6 2023/09/08 05:56:22 yasuoka Exp $ */
/*
* Copyright (c) 2013 Internet Initiative Japan Inc.
@ -122,6 +122,7 @@ struct radius_query {
int req_modified;
char username[256]; /* original username */
TAILQ_ENTRY(radius_query) next;
struct radiusd_module_ref *deco;
};
#ifndef nitems
#define nitems(_x) (sizeof((_x)) / sizeof((_x)[0]))
@ -149,6 +150,12 @@ struct radius_query {
#define MODULE_DO_ACCSREQ(_m) \
((_m)->fd >= 0 && \
((_m)->capabilities & RADIUSD_MODULE_CAP_ACCSREQ) != 0)
#define MODULE_DO_REQDECO(_m) \
((_m)->fd >= 0 && \
((_m)->capabilities & RADIUSD_MODULE_CAP_REQDECO) != 0)
#define MODULE_DO_RESDECO(_m) \
((_m)->fd >= 0 && \
((_m)->capabilities & RADIUSD_MODULE_CAP_RESDECO) != 0)
extern struct radiusd_module mod_standard;
extern struct radiusd_module mod_radius;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: radiusd_module.c,v 1.13 2019/06/28 13:32:49 deraadt Exp $ */
/* $OpenBSD: radiusd_module.c,v 1.14 2023/09/08 05:56:22 yasuoka Exp $ */
/*
* Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net>
@ -46,6 +46,10 @@ static void (*module_userpass) (void *, u_int, const char *, const char *)
= NULL;
static void (*module_access_request) (void *, u_int, const u_char *,
size_t) = NULL;
static void (*module_request_decoration) (void *, u_int, const u_char *,
size_t) = NULL;
static void (*module_response_decoration) (void *, u_int, const u_char *,
size_t) = NULL;
struct module_base {
void *ctx;
@ -73,7 +77,6 @@ static int module_imsg_handler(struct module_base *, struct imsg *);
#ifdef USE_LIBEVENT
static void module_on_event(int, short, void *);
#endif
static void module_stop(struct module_base *);
static void module_reset_event(struct module_base *);
struct module_base *
@ -90,6 +93,8 @@ module_create(int sock, void *ctx, struct module_handlers *handler)
module_userpass = handler->userpass;
module_access_request = handler->access_request;
module_config_set = handler->config_set;
module_request_decoration = handler->request_decoration;
module_response_decoration = handler->response_decoration;
module_start_module = handler->start;
module_stop_module = handler->stop;
@ -140,6 +145,10 @@ module_load(struct module_base *base)
load.cap |= RADIUSD_MODULE_CAP_USERPASS;
if (module_access_request != NULL)
load.cap |= RADIUSD_MODULE_CAP_ACCSREQ;
if (module_request_decoration != NULL)
load.cap |= RADIUSD_MODULE_CAP_REQDECO;
if (module_response_decoration != NULL)
load.cap |= RADIUSD_MODULE_CAP_RESDECO;
imsg_compose(&base->ibuf, IMSG_RADIUSD_MODULE_LOAD, 0, 0, -1, &load,
sizeof(load));
imsg_flush(&base->ibuf);
@ -260,6 +269,22 @@ module_accsreq_aborted(struct module_base *base, u_int q_id)
return (ret);
}
int
module_reqdeco_done(struct module_base *base, u_int q_id, const u_char *pkt,
size_t pktlen)
{
return (module_common_radpkt(base, IMSG_RADIUSD_MODULE_REQDECO_DONE,
q_id, pkt, pktlen));
}
int
module_resdeco_done(struct module_base *base, u_int q_id, const u_char *pkt,
size_t pktlen)
{
return (module_common_radpkt(base, IMSG_RADIUSD_MODULE_RESDECO_DONE,
q_id, pkt, pktlen));
}
static int
module_common_radpkt(struct module_base *base, uint32_t imsg_type, u_int q_id,
const u_char *pkt, size_t pktlen)
@ -271,19 +296,22 @@ module_common_radpkt(struct module_base *base, uint32_t imsg_type, u_int q_id,
len = pktlen;
ans.q_id = q_id;
ans.pktlen = pktlen;
while (off < len) {
ans.final = false;
while (!ans.final) {
siz = MAX_IMSGSIZE - sizeof(ans);
if (len - off > siz)
ans.final = false;
else {
if (len - off <= siz) {
ans.final = true;
siz = len - off;
}
iov[0].iov_base = &ans;
iov[0].iov_len = sizeof(ans);
iov[1].iov_base = (u_char *)pkt + off;
iov[1].iov_len = siz;
ret = imsg_composev(&base->ibuf, imsg_type, 0, 0, -1, iov, 2);
if (siz > 0) {
iov[1].iov_base = (u_char *)pkt + off;
iov[1].iov_len = siz;
}
ret = imsg_composev(&base->ibuf, imsg_type, 0, 0, -1, iov,
(siz > 0)? 2 : 1);
if (ret == -1)
break;
off += siz;
@ -305,7 +333,6 @@ module_recv_imsg(struct module_base *base)
module_stop(base);
return (-1);
}
for (;;) {
if ((n = imsg_get(&base->ibuf, &imsg)) == -1) {
syslog(LOG_ERR, "%s: imsg_get(): %m", __func__);
@ -410,19 +437,40 @@ module_imsg_handler(struct module_base *base, struct imsg *imsg)
break;
}
case IMSG_RADIUSD_MODULE_ACCSREQ:
case IMSG_RADIUSD_MODULE_REQDECO:
case IMSG_RADIUSD_MODULE_RESDECO:
{
struct radiusd_module_radpkt_arg *accessreq;
int chunklen;
const char *typestr;
if (module_access_request == NULL) {
syslog(LOG_ERR, "Received ACCSREQ message, but "
"module doesn't support");
break;
if (imsg->hdr.type == IMSG_RADIUSD_MODULE_ACCSREQ) {
if (module_access_request == NULL) {
syslog(LOG_ERR, "Received ACCSREQ message, but "
"module doesn't support");
break;
}
typestr = "ACCSREQ";
} else if (imsg->hdr.type == IMSG_RADIUSD_MODULE_REQDECO) {
if (module_request_decoration == NULL) {
syslog(LOG_ERR, "Received REQDECO message, but "
"module doesn't support");
break;
}
typestr = "REQDECO";
} else {
if (module_response_decoration == NULL) {
syslog(LOG_ERR, "Received RESDECO message, but "
"module doesn't support");
break;
}
typestr = "RESDECO";
}
if (datalen <
(ssize_t)sizeof(struct radiusd_module_radpkt_arg)) {
syslog(LOG_ERR, "Received ACCSREQ message, but "
"length is wrong");
syslog(LOG_ERR, "Received %s message, but "
"length is wrong", typestr);
break;
}
accessreq = (struct radiusd_module_radpkt_arg *)imsg->data;
@ -431,7 +479,7 @@ module_imsg_handler(struct module_base *base, struct imsg *imsg)
if ((nradpkt = realloc(base->radpkt,
accessreq->pktlen)) == NULL) {
syslog(LOG_ERR, "Could not handle received "
"ACCSREQ message: %m");
"%s message: %m", typestr);
base->radpktoff = 0;
goto accsreq_out;
}
@ -441,8 +489,8 @@ module_imsg_handler(struct module_base *base, struct imsg *imsg)
chunklen = datalen - sizeof(struct radiusd_module_radpkt_arg);
if (chunklen > base->radpktsiz - base->radpktoff){
syslog(LOG_ERR,
"Could not handle received ACCSREQ message: "
"received length is too big");
"Could not handle received %s message: "
"received length is too big", typestr);
base->radpktoff = 0;
goto accsreq_out;
}
@ -453,13 +501,20 @@ module_imsg_handler(struct module_base *base, struct imsg *imsg)
goto accsreq_out;
if (base->radpktoff != accessreq->pktlen) {
syslog(LOG_ERR,
"Could not handle received ACCSREQ "
"message: length is mismatch");
"Could not handle received %s "
"message: length is mismatch", typestr);
base->radpktoff = 0;
goto accsreq_out;
}
module_access_request(base->ctx, accessreq->q_id,
base->radpkt, base->radpktoff);
if (imsg->hdr.type == IMSG_RADIUSD_MODULE_ACCSREQ)
module_access_request(base->ctx, accessreq->q_id,
base->radpkt, base->radpktoff);
else if (imsg->hdr.type == IMSG_RADIUSD_MODULE_REQDECO)
module_request_decoration(base->ctx, accessreq->q_id,
base->radpkt, base->radpktoff);
else
module_response_decoration(base->ctx, accessreq->q_id,
base->radpkt, base->radpktoff);
base->radpktoff = 0;
accsreq_out:
break;
@ -469,7 +524,7 @@ accsreq_out:
return (0);
}
static void
void
module_stop(struct module_base *base)
{
if (module_stop_module != NULL)

View file

@ -35,8 +35,13 @@ struct module_handlers {
void (*access_request)(void *ctx, u_int query_id, const u_char *pkt,
size_t pktlen);
/* User-Password Attribute is encrypted if the module has the secret */
void (*request_decoration)(void *ctx, u_int query_id, const u_char *pkt,
size_t pktlen);
void (*response_decoration)(void *ctx, u_int query_id,
const u_char *pkt, size_t pktlen);
};
#define SYNTAX_ASSERT(_cond, _msg) \
@ -51,6 +56,7 @@ __BEGIN_DECLS
struct module_base *module_create(int, void *, struct module_handlers *);
void module_start(struct module_base *);
void module_stop(struct module_base *);
int module_run(struct module_base *);
void module_destroy(struct module_base *);
void module_load(struct module_base *);
@ -67,6 +73,10 @@ int module_userpass_fail(struct module_base *, u_int,
int module_accsreq_answer(struct module_base *, u_int,
const u_char *, size_t);
int module_accsreq_aborted(struct module_base *, u_int);
int module_reqdeco_done(struct module_base *, u_int,
const u_char *, size_t);
int module_resdeco_done(struct module_base *, u_int,
const u_char *, size_t);
__END_DECLS

View file

@ -0,0 +1,298 @@
/* $OpenBSD: radiusd_standard.c,v 1.1 2023/09/08 05:56:22 yasuoka Exp $ */
/*
* Copyright (c) 2013, 2023 Internet Initiative Japan Inc.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <sys/queue.h>
#include <err.h>
#include <errno.h>
#include <radius.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include "radiusd.h"
#include "radiusd_module.h"
TAILQ_HEAD(attrs,attr);
struct attr {
uint8_t type;
uint32_t vendor;
uint32_t vtype;
TAILQ_ENTRY(attr) next;
};
struct module_standard {
struct module_base *base;
bool strip_atmark_realm;
bool strip_nt_domain;
struct attrs remove_reqattrs;
struct attrs remove_resattrs;
};
static void module_standard_config_set(void *, const char *, int,
char * const *);
static void module_standard_reqdeco(void *, u_int, const u_char *, size_t);
static void module_standard_resdeco(void *, u_int, const u_char *, size_t);
int
main(int argc, char *argv[])
{
struct module_standard module_standard;
struct module_handlers handlers = {
.config_set = module_standard_config_set,
.request_decoration = module_standard_reqdeco,
.response_decoration = module_standard_resdeco
};
struct attr *attr;
memset(&module_standard, 0, sizeof(module_standard));
TAILQ_INIT(&module_standard.remove_reqattrs);
TAILQ_INIT(&module_standard.remove_resattrs);
if ((module_standard.base = module_create(
STDIN_FILENO, &module_standard, &handlers)) == NULL)
err(1, "Could not create a module instance");
module_drop_privilege(module_standard.base);
if (pledge("stdio", NULL) == -1)
err(1, "pledge");
module_load(module_standard.base);
openlog(NULL, LOG_PID, LOG_DAEMON);
while (module_run(module_standard.base) == 0)
;
module_destroy(module_standard.base);
while ((attr = TAILQ_FIRST(&module_standard.remove_reqattrs)) != NULL) {
TAILQ_REMOVE(&module_standard.remove_reqattrs, attr, next);
freezero(attr, sizeof(struct attr));
}
while ((attr = TAILQ_FIRST(&module_standard.remove_resattrs)) != NULL) {
TAILQ_REMOVE(&module_standard.remove_resattrs, attr, next);
freezero(attr, sizeof(struct attr));
}
exit(EXIT_SUCCESS);
}
static void
module_standard_config_set(void *ctx, const char *name, int argc,
char * const * argv)
{
struct module_standard *module = ctx;
struct attr *attr;
const char *errmsg = "none";
const char *errstr;
if (strcmp(name, "strip-atmark-realm") == 0) {
SYNTAX_ASSERT(argc == 1,
"`strip-atmark-realm' must have only one argment");
if (strcmp(argv[0], "true") == 0)
module->strip_atmark_realm = true;
else if (strcmp(argv[0], "false") == 0)
module->strip_atmark_realm = false;
else
SYNTAX_ASSERT(0,
"`strip-atmark-realm' must `true' or `false'");
} else if (strcmp(name, "strip-nt-domain") == 0) {
SYNTAX_ASSERT(argc == 1,
"`strip-nt-domain' must have only one argment");
if (strcmp(argv[0], "true") == 0)
module->strip_nt_domain = true;
else if (strcmp(argv[0], "false") == 0)
module->strip_nt_domain = false;
else
SYNTAX_ASSERT(0,
"`strip-nt-domain' must `true' or `false'");
} else if (strcmp(name, "remove-request-attribute") == 0 ||
strcmp(name, "remove-response-attribute") == 0) {
struct attrs *attrs;
if (strcmp(name, "remove-request-attribute") == 0) {
SYNTAX_ASSERT(argc == 1 || argc == 2,
"`remove-request-attribute' must have one or two "
"argment");
attrs = &module->remove_reqattrs;
} else {
SYNTAX_ASSERT(argc == 1 || argc == 2,
"`remove-response-attribute' must have one or two "
"argment");
attrs = &module->remove_resattrs;
}
if ((attr = calloc(1, sizeof(struct attr))) == NULL) {
module_send_message(module->base, IMSG_NG,
"Out of memory: %s", strerror(errno));
}
if (argc == 1) {
attr->type = strtonum(argv[0], 0, 255, &errstr);
if (errstr == NULL &&
attr->type != RADIUS_TYPE_VENDOR_SPECIFIC) {
TAILQ_INSERT_TAIL(attrs, attr, next);
attr = NULL;
}
} else {
attr->type = RADIUS_TYPE_VENDOR_SPECIFIC;
attr->vendor = strtonum(argv[0], 0, UINT32_MAX,
&errstr);
if (errstr == NULL)
attr->vtype = strtonum(argv[1], 0, 255,
&errstr);
if (errstr == NULL) {
TAILQ_INSERT_TAIL(attrs, attr, next);
attr = NULL;
}
}
freezero(attr, sizeof(struct attr));
if (strcmp(name, "remove-request-attribute") == 0)
SYNTAX_ASSERT(attr == NULL,
"wrong number for `remove-request-attribute`");
else
SYNTAX_ASSERT(attr == NULL,
"wrong number for `remove-response-attribute`");
} else if (strncmp(name, "_", 1) == 0)
/* nothing */; /* ignore all internal messages */
else {
module_send_message(module->base, IMSG_NG,
"Unknown config parameter name `%s'", name);
return;
}
module_send_message(module->base, IMSG_OK, NULL);
return;
syntax_error:
module_send_message(module->base, IMSG_NG, "%s", errmsg);
}
/* request message decoration */
static void
module_standard_reqdeco(void *ctx, u_int q_id, const u_char *pkt, size_t pktlen)
{
struct module_standard *module = ctx;
RADIUS_PACKET *radpkt = NULL;
int changed = 0;
char *ch, *username, buf[256];
struct attr *attr;
if (module->strip_atmark_realm || module->strip_nt_domain) {
if ((radpkt = radius_convert_packet(pkt, pktlen)) == NULL) {
syslog(LOG_ERR,
"%s: radius_convert_packet() failed: %m", __func__);
module_stop(module->base);
return;
}
username = buf;
if (radius_get_string_attr(radpkt, RADIUS_TYPE_USER_NAME,
username, sizeof(buf)) != 0) {
syslog(LOG_WARNING,
"standard: q=%u could not get User-Name attribute",
q_id);
goto skip;
}
if (module->strip_atmark_realm &&
(ch = strrchr(username, '@')) != NULL) {
*ch = '\0';
changed++;
}
if (module->strip_nt_domain &&
(ch = strchr(username, '\\')) != NULL) {
username = ch + 1;
changed++;
}
if (changed > 0) {
radius_del_attr_all(radpkt, RADIUS_TYPE_USER_NAME);
radius_put_string_attr(radpkt,
RADIUS_TYPE_USER_NAME, username);
}
}
skip:
TAILQ_FOREACH(attr, &module->remove_reqattrs, next) {
if (radpkt == NULL &&
(radpkt = radius_convert_packet(pkt, pktlen)) == NULL) {
syslog(LOG_ERR,
"%s: radius_convert_packet() failed: %m", __func__);
module_stop(module->base);
return;
}
if (attr->type != RADIUS_TYPE_VENDOR_SPECIFIC)
radius_del_attr_all(radpkt, attr->type);
else
radius_del_vs_attr_all(radpkt, attr->vendor,
attr->vtype);
}
if (radpkt == NULL) {
pkt = NULL;
pktlen = 0;
} else {
pkt = radius_get_data(radpkt);
pktlen = radius_get_length(radpkt);
}
if (module_reqdeco_done(module->base, q_id, pkt, pktlen) == -1) {
syslog(LOG_ERR, "%s: module_reqdeco_done() failed: %m",
__func__);
module_stop(module->base);
}
if (radpkt != NULL)
radius_delete_packet(radpkt);
}
/* response message decoration */
static void
module_standard_resdeco(void *ctx, u_int q_id, const u_char *pkt, size_t pktlen)
{
struct module_standard *module = ctx;
RADIUS_PACKET *radpkt = NULL;
struct attr *attr;
TAILQ_FOREACH(attr, &module->remove_reqattrs, next) {
if (radpkt == NULL &&
(radpkt = radius_convert_packet(pkt, pktlen)) == NULL) {
syslog(LOG_ERR,
"%s: radius_convert_packet() failed: %m", __func__);
module_stop(module->base);
return;
}
if (attr->type != RADIUS_TYPE_VENDOR_SPECIFIC)
radius_del_attr_all(radpkt, attr->type);
else
radius_del_vs_attr_all(radpkt, attr->vendor,
attr->vtype);
}
if (radpkt == NULL) {
pkt = NULL;
pktlen = 0;
} else {
pkt = radius_get_data(radpkt);
pktlen = radius_get_length(radpkt);
}
if (module_resdeco_done(module->base, q_id, pkt, pktlen) == -1) {
syslog(LOG_ERR, "%s: module_resdeco_done() failed: %m",
__func__);
module_stop(module->base);
}
if (radpkt != NULL)
radius_delete_packet(radpkt);
}

View file

@ -0,0 +1,8 @@
# $OpenBSD: Makefile,v 1.1 2023/09/08 05:56:22 yasuoka Exp $
PROG= radiusd_standard
BINDIR= /usr/libexec/radiusd
SRCS= radiusd_standard.c radiusd_module.c
LDADD= -lutil -lradius -lcrypto
NOMAN= #
.include <bsd.prog.mk>