Sync: merge r216133 through r216338 from ^/head.

This commit is contained in:
dim 2010-12-09 22:01:15 +00:00
commit a3786f65f1
681 changed files with 17777 additions and 4604 deletions

View File

@ -22,16 +22,33 @@
# grep '+=' /usr/src/tools/build/mk/OptionalObsoleteFiles.inc | sort -u) | \
# sort | uniq -d
#
# To find regular duplicates not dependant on optional components, you can
# also use something that will not give you false positives, e.g.:
# for t in `make -V TARGETS universe`; do
# __MAKE_CONF=/dev/null make -f Makefile.inc1 TARGET=$t \
# -V OLD_FILES -V OLD_LIBS -V OLD_DIRS check-old | \
# xargs -n1 | sort | uniq -d;
# done
#
# For optional components, you can use the following to see if some entries
# in OptionalObsoleteFiles.inc have been obsoleted by ObsoleteFiles.inc
# for o in tools/build/options/WITH*; do
# __MAKE_CONF=/dev/null make -f Makefile.inc1 -D${o##*/} \
# -V OLD_FILES -V OLD_LIBS -V OLD_DIRS check-old | \
# xargs -n1 | sort | uniq -d;
# done
# 20101114: Remove long-obsolete MAKEDEV.8
OLD_FILES+=usr/share/man/man8/MAKEDEV.8.gz
# 20101112: vgonel(9) has gone to private API a while ago
OLD_FILES+=usr/share/man/man9/vgonel.9.gz
# 20101112: removed gasp.info
OLD_FILES+=usr/share/info/gasp.info.gz
# 20101109: headers moved to machine/ to x86/
# 20101109: headers moved from machine/ to x86/
.if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "i386"
OLD_FILES+=usr/include/machine/mptable.h
.endif
# 20101101: headers moved to machine/ to x86/
# 20101101: headers moved from machine/ to x86/
.if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "i386"
OLD_FILES+=usr/include/machine/apicreg.h
OLD_FILES+=usr/include/machine/mca.h

View File

@ -100,7 +100,8 @@ static void setcurjob(struct job *);
static void deljob(struct job *);
static struct job *getcurjob(struct job *);
#endif
static void showjob(struct job *, pid_t, int);
static void printjobcmd(struct job *);
static void showjob(struct job *, int);
/*
@ -205,8 +206,7 @@ fgcmd(int argc __unused, char **argv)
jp = getjob(argv[1]);
if (jp->jobctl == 0)
error("job not created under job control");
out1str(jp->ps[0].cmd);
out1c('\n');
printjobcmd(jp);
flushout(&output);
pgrp = jp->ps[0].pid;
tcsetpgrp(ttyfd, pgrp);
@ -235,8 +235,7 @@ bgcmd(int argc, char **argv)
jp->foreground = 0;
fmtstr(s, 64, "[%td] ", jp - jobtab + 1);
out1str(s);
out1str(jp->ps[0].cmd);
out1c('\n');
printjobcmd(jp);
} while (--argc > 1);
return 0;
}
@ -296,19 +295,33 @@ jobscmd(int argc, char *argv[])
showjobs(0, mode);
else
while ((id = *argv++) != NULL)
showjob(getjob(id), 0, mode);
showjob(getjob(id), mode);
return (0);
}
static void
showjob(struct job *jp, pid_t pid, int mode)
printjobcmd(struct job *jp)
{
struct procstat *ps;
int i;
for (ps = jp->ps, i = jp->nprocs ; --i >= 0 ; ps++) {
out1str(ps->cmd);
if (i > 0)
out1str(" | ");
}
out1c('\n');
}
static void
showjob(struct job *jp, int mode)
{
char s[64];
char statestr[64];
struct procstat *ps;
struct job *j;
int col, curr, i, jobno, prev, procno;
pid_t ppid;
char c;
procno = (mode == SHOWJOBS_PGIDS) ? 1 : jp->nprocs;
@ -321,16 +334,44 @@ showjob(struct job *jp, pid_t pid, int mode)
prev = j - jobtab + 1;
}
#endif
ps = jp->ps + jp->nprocs - 1;
if (jp->state == 0) {
strcpy(statestr, "Running");
#if JOBS
} else if (jp->state == JOBSTOPPED) {
while (!WIFSTOPPED(ps->status) && ps > jp->ps)
ps--;
if (WIFSTOPPED(ps->status))
i = WSTOPSIG(ps->status);
else
i = -1;
if (i > 0 && i < sys_nsig && sys_siglist[i])
strcpy(statestr, sys_siglist[i]);
else
strcpy(statestr, "Suspended");
#endif
} else if (WIFEXITED(ps->status)) {
if (WEXITSTATUS(ps->status) == 0)
strcpy(statestr, "Done");
else
fmtstr(statestr, 64, "Done(%d)",
WEXITSTATUS(ps->status));
} else {
i = WTERMSIG(ps->status);
if (i > 0 && i < sys_nsig && sys_siglist[i])
strcpy(statestr, sys_siglist[i]);
else
fmtstr(statestr, 64, "Signal %d", i);
if (WCOREDUMP(ps->status))
strcat(statestr, " (core dumped)");
}
for (ps = jp->ps ; ; ps++) { /* for each process */
if (mode == SHOWJOBS_PIDS || mode == SHOWJOBS_PGIDS) {
ppid = (mode == SHOWJOBS_PIDS) ? ps->pid :
getpgid(ps->pid);
out1fmt("%d\n", (int)ppid);
out1fmt("%d\n", (int)ps->pid);
goto skip;
}
if (mode != SHOWJOBS_VERBOSE && ps != jp->ps && pid == 0)
goto skip;
if (pid != 0 && pid != ps->pid)
if (mode != SHOWJOBS_VERBOSE && ps != jp->ps)
goto skip;
if (jobno == curr && ps == jp->ps)
c = '+';
@ -349,39 +390,19 @@ showjob(struct job *jp, pid_t pid, int mode)
out1str(s);
col += strlen(s);
}
s[0] = '\0';
if (ps != jp->ps) {
*s = '\0';
} else if (ps->status == -1) {
strcpy(s, "Running");
} else if (WIFEXITED(ps->status)) {
if (WEXITSTATUS(ps->status) == 0)
strcpy(s, "Done");
else
fmtstr(s, 64, "Done (%d)",
WEXITSTATUS(ps->status));
} else {
#if JOBS
if (WIFSTOPPED(ps->status))
i = WSTOPSIG(ps->status);
else
#endif
i = WTERMSIG(ps->status);
if ((i & 0x7F) < sys_nsig && sys_siglist[i & 0x7F])
scopy(sys_siglist[i & 0x7F], s);
else
fmtstr(s, 64, "Signal %d", i & 0x7F);
if (WCOREDUMP(ps->status))
strcat(s, " (core dumped)");
if (ps == jp->ps) {
out1str(statestr);
col += strlen(statestr);
}
out1str(s);
col += strlen(s);
do {
out1c(' ');
col++;
} while (col < 30);
out1str(ps->cmd);
out1c('\n');
if (mode == SHOWJOBS_VERBOSE) {
out1str(ps->cmd);
out1c('\n');
} else
printjobcmd(jp);
skip: if (--procno <= 0)
break;
}
@ -413,7 +434,7 @@ showjobs(int change, int mode)
}
if (change && ! jp->changed)
continue;
showjob(jp, 0, mode);
showjob(jp, mode);
jp->changed = 0;
/* Hack: discard jobs for which $! has not been referenced
* in interactive mode when they terminate.
@ -769,7 +790,7 @@ forkshell(struct job *jp, union node *n, int mode)
TRACE(("forkshell(%%%td, %p, %d) called\n", jp - jobtab, (void *)n,
mode));
INTOFF;
if (mode == FORK_BG)
if (mode == FORK_BG && (jp == NULL || jp->nprocs == 0))
checkzombies();
flushall();
pid = fork();
@ -961,7 +982,7 @@ dowait(int block, struct job *job)
int done;
int stopped;
int sig;
int i;
int coredump;
in_dowait++;
TRACE(("dowait(%d) called\n", block));
@ -983,7 +1004,7 @@ dowait(int block, struct job *job)
INTOFF;
thisjob = NULL;
for (jp = jobtab ; jp < jobtab + njobs ; jp++) {
if (jp->used) {
if (jp->used && jp->nprocs > 0) {
done = 1;
stopped = 1;
for (sp = jp->ps ; sp < jp->ps + jp->nprocs ; sp++) {
@ -1020,36 +1041,29 @@ dowait(int block, struct job *job)
}
}
INTON;
if (! rootshell || ! iflag || (job && thisjob == job)) {
#if JOBS
if (WIFSTOPPED(status))
sig = WSTOPSIG(status);
else
#endif
{
if (WIFEXITED(status))
sig = 0;
if (!thisjob || thisjob->state == 0)
;
else if ((!rootshell || !iflag || thisjob == job) &&
thisjob->foreground && thisjob->state != JOBSTOPPED) {
sig = 0;
coredump = 0;
for (sp = thisjob->ps; sp < thisjob->ps + thisjob->nprocs; sp++)
if (WIFSIGNALED(sp->status)) {
sig = WTERMSIG(sp->status);
coredump = WCOREDUMP(sp->status);
}
if (sig > 0 && sig != SIGINT && sig != SIGPIPE) {
if (sig < sys_nsig && sys_siglist[sig])
out1str(sys_siglist[sig]);
else
sig = WTERMSIG(status);
}
if (sig != 0 && sig != SIGINT && sig != SIGPIPE) {
if (!mflag ||
(thisjob->foreground && !WIFSTOPPED(status))) {
i = WTERMSIG(status);
if ((i & 0x7F) < sys_nsig && sys_siglist[i & 0x7F])
out1str(sys_siglist[i & 0x7F]);
else
out1fmt("Signal %d", i & 0x7F);
if (WCOREDUMP(status))
out1str(" (core dumped)");
out1c('\n');
} else
showjob(thisjob, pid, SHOWJOBS_DEFAULT);
out1fmt("Signal %d", sig);
if (coredump)
out1str(" (core dumped)");
out1c('\n');
}
} else {
TRACE(("Not printing status, rootshell=%d, job=%p\n", rootshell, job));
if (thisjob)
thisjob->changed = 1;
thisjob->changed = 1;
}
return pid;
}
@ -1300,13 +1314,46 @@ cmdputs(const char *s)
if (--cmdnleft > 0)
*q++ = '{';
subtype = *p++;
if ((subtype & VSTYPE) == VSLENGTH && --cmdnleft > 0)
*q++ = '#';
} else if (c == '=' && subtype != 0) {
*q++ = "}-+?="[(subtype & VSTYPE) - VSNORMAL];
*q = "}-+?=##%%\0X"[(subtype & VSTYPE) - VSNORMAL];
if (*q)
q++;
else
cmdnleft++;
if (((subtype & VSTYPE) == VSTRIMLEFTMAX ||
(subtype & VSTYPE) == VSTRIMRIGHTMAX) &&
--cmdnleft > 0)
*q = q[-1], q++;
subtype = 0;
} else if (c == CTLENDVAR) {
*q++ = '}';
} else if (c == CTLBACKQ || c == CTLBACKQ+CTLQUOTE)
cmdnleft++; /* ignore it */
} else if (c == CTLBACKQ || c == CTLBACKQ+CTLQUOTE) {
cmdnleft -= 5;
if (cmdnleft > 0) {
*q++ = '$';
*q++ = '(';
*q++ = '.';
*q++ = '.';
*q++ = '.';
*q++ = ')';
}
} else if (c == CTLARI) {
cmdnleft -= 2;
if (cmdnleft > 0) {
*q++ = '$';
*q++ = '(';
*q++ = '(';
}
p++;
} else if (c == CTLENDARI) {
if (--cmdnleft > 0) {
*q++ = ')';
*q++ = ')';
}
} else if (c == CTLQUOTEMARK || c == CTLQUOTEEND)
cmdnleft++; /* ignore */
else
*q++ = c;
if (--cmdnleft <= 0) {

View File

@ -32,7 +32,7 @@
.\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95
.\" $FreeBSD$
.\"
.Dd December 1, 2010
.Dd December 3, 2010
.Dt SH 1
.Os
.Sh NAME
@ -1593,12 +1593,7 @@ To include a
.Ql - ,
make it the first or last character listed.
.Ss Built-in Commands
This section lists the commands which
are built-in because they need to perform some operation
that cannot be performed by a separate process.
In addition to
these, built-in versions of essential utilities
are provided for efficiency.
This section lists the built-in commands.
.Bl -tag -width indent
.It Ic \&:
A null command that returns a 0 (true) exit value.
@ -1649,15 +1644,19 @@ subsection.
Continue the specified jobs
(or the current job if no jobs are given)
in the background.
.It Ic bind Oo Fl aeklrsv Oc Oo Ar key Oo Ar command Oc Oc
List or alter key bindings for the line editor.
This command is documented in
.Xr editrc 5 .
.It Ic break Op Ar num
See the
.Sx Flow-Control Constructs
subsection.
.It Ic builtin Ar cmd Op Ar arg ...
Execute the specified built-in command,
.Ar cmd .
This is useful when the user wishes to override a shell function
with the same name as a built-in command.
.It Ic bind Oo Fl aeklrsv Oc Oo Ar key Oo Ar command Oc Oc
List or alter key bindings for the line editor.
This command is documented in
.Xr editrc 5 .
.It Ic cd Oo Fl L | P Oc Op Ar directory
Switch to the specified
.Ar directory ,
@ -1759,6 +1758,10 @@ a shell keyword
or
an alias for
.Ar value .
.It Ic continue Op Ar num
See the
.Sx Flow-Control Constructs
subsection.
.It Ic echo Oo Fl e | n Oc Op Ar string ...
Print a space-separated list of the arguments to the standard output
and append a newline character.

View File

@ -48,11 +48,13 @@
static int read_efi_label(nvlist_t *config, diskaddr_t *sb);
#ifdef sun
#if defined(__i386) || defined(__amd64)
#define BOOTCMD "installgrub(1M)"
#else
#define BOOTCMD "installboot(1M)"
#endif
#endif /* sun */
/*
* ====================================================================
@ -1889,14 +1891,15 @@ zpool_vdev_attach(zpool_handle_t *zhp,
if (ret == 0) {
if (rootpool) {
/*
* XXX - This should be removed once we can
* automatically install the bootblocks on the
* newly attached disk.
*/
(void) fprintf(stderr, dgettext(TEXT_DOMAIN, "Please "
"be sure to invoke %s to make '%s' bootable.\n"),
BOOTCMD, new_disk);
(void) fprintf(stderr, dgettext(TEXT_DOMAIN, "If "
"you boot from pool '%s', you may need to update\n"
"boot code on newly attached disk '%s'.\n\n"
"Assuming you use GPT partitioning and 'da0' is "
"your new boot disk\n"
"you may use the following command:\n\n"
"\tgpart bootcode -b /boot/pmbr -p "
"/boot/gptzfsboot -i 1 da0\n\n"),
zhp->zpool_name, new_disk);
}
return (0);
}

View File

@ -1,3 +1,55 @@
--- 9.6-ESV-R3 released ---
2972. [bug] win32: address windows socket errors. [RT #21906]
2971. [bug] Fixed a bug that caused journal files not to be
compacted on Windows systems as a result of
non-POSIX-compliant rename() semantics. [RT #22434]
2970. [security] Adding a NO DATA negative cache entry failed to clear
any matching RRSIG records. A subsequent lookup of
of NO DATA cache entry could trigger a INSIST when the
unexpected RRSIG was also returned with the NO DATA
cache entry.
CVE-2010-3613, VU#706148. [RT #22288]
2969. [security] Fix acl type processing so that allow-query works
in options and view statements. Also add a new
set of tests to verify proper functioning.
CVE-2010-3615, VU#510208. [RT #22418]
2968. [security] Named could fail to prove a data set was insecure
before marking it as insecure. One set of conditions
that can trigger this occurs naturally when rolling
DNSKEY algorithms.
CVE-2010-3614, VU#837744. [RT #22309]
2967. [bug] 'host -D' now turns on debugging messages earlier.
[RT #22361]
2966. [bug] isc_print_vsnprintf() failed to check if there was
space available in the buffer when adding a left
justified character with a non zero width,
(e.g. "%-1c"). [RT #22270]
2964. [bug] view->queryacl was being overloaded. Seperate the
usage into view->queryacl, view->cacheacl and
view->queryonacl. [RT #22114]
2962. [port] win32: add more dependencies to BINDBuild.dsw.
[RT #22062]
2952. [port] win32: named-checkzone and named-checkconf failed
to initialise winsock. [RT #21932]
2951. [bug] named failed to generate a correct signed response
in a optout, delegation only zone with no secure
delegations. [RT #22007]
--- 9.6-ESV-R2 released ---
2939. [func] Check that named successfully skips NSEC3 records

View File

@ -0,0 +1,225 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!--
- Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
-
- Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- AND FITNESS. IN NO EVENT SHALL ISC 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.
-->
<!-- $Id: RELEASE-NOTES-BIND-9.6-ESV.html,v 1.1.2.2 2010/11/29 01:16:39 tbox Exp $ -->
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title></title><link rel="stylesheet" type="text/css" href="release-notes.css" /><meta name="generator" content="DocBook XSL Stylesheets V1.76.1" /></head><body><div class="article"><div class="titlepage"><hr /></div>
<div class="section" title="Introduction"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="id36111950"></a>Introduction</h2></div></div></div>
<p>
BIND 9.6-ESV-R3 is a maintenance release for BIND 9.6-ESV.
</p>
<p>
This document summarizes changes from BIND 9.6-ESV-R1 to BIND 9.6-ESV-R3.
Please see the CHANGES file in the source code release for a
complete list of all changes.
</p>
</div>
<div class="section" title="Download"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="id36112014"></a>Download</h2></div></div></div>
<p>
The latest release of BIND 9 software can always be found
on our web site at
<a class="ulink" href="http://www.isc.org/software/bind" target="_top">http://www.isc.org/software/bind</a>.
There you will find additional information about each release,
source code, and some pre-compiled versions for certain operating
systems.
</p>
</div>
<div class="section" title="Support"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="id36112037"></a>Support</h2></div></div></div>
<p>Product support information is available on
<a class="ulink" href="http://www.isc.org/services/support" target="_top">http://www.isc.org/services/support</a>
for paid support options. Free support is provided by our user
community via a mailing list. Information on all public email
lists is available at
<a class="ulink" href="https://lists.isc.org/mailman/listinfo" target="_top">https://lists.isc.org/mailman/listinfo</a>.
</p>
</div>
<div class="section" title="New Features"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="id36111986"></a>New Features</h2></div></div></div>
<div class="section" title="9.6-ESV-R2"><div class="titlepage"><div><div><h3 class="title"><a id="id36112025"></a>9.6-ESV-R2</h3></div></div></div>
<p>None.</p>
</div>
<div class="section" title="9.6-ESV-R3"><div class="titlepage"><div><div><h3 class="title"><a id="id36112098"></a>9.6-ESV-R3</h3></div></div></div>
<p>None.</p>
</div>
</div>
<div class="section" title="Feature Changes"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="id36112120"></a>Feature Changes</h2></div></div></div>
<div class="section" title="9.6-ESV-R2"><div class="titlepage"><div><div><h3 class="title"><a id="id36112125"></a>9.6-ESV-R2</h3></div></div></div>
<p>None.</p>
</div>
<div class="section" title="9.6-ESV-R3"><div class="titlepage"><div><div><h3 class="title"><a id="id36112135"></a>9.6-ESV-R3</h3></div></div></div>
<p>None.</p>
</div>
</div>
<div class="section" title="Security Fixes"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="id36112146"></a>Security Fixes</h2></div></div></div>
<div class="section" title="9.6-ESV-R2"><div class="titlepage"><div><div><h3 class="title"><a id="id36112151"></a>9.6-ESV-R2</h3></div></div></div>
<p>None.</p>
</div>
<div class="section" title="9.6-ESV-R3"><div class="titlepage"><div><div><h3 class="title"><a id="id36112160"></a>9.6-ESV-R3</h3></div></div></div>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
Adding a NO DATA signed negative response to cache failed to clear
any matching RRSIG records already in cache. A subsequent lookup
of the cached NO DATA entry could crash named (INSIST) when the
unexpected RRSIG was also returned with the NO DATA cache entry.
[RT #22288] [CVE-2010-3613] [VU#706148]
</li><li class="listitem">
BIND, acting as a DNSSEC validator, was determining if the NS RRset
is insecure based on a value that could mean either that the RRset
is actually insecure or that there wasn't a matching key for the RRSIG
in the DNSKEY RRset when resuming from validating the DNSKEY RRset.
This can happen when in the middle of a DNSKEY algorithm rollover,
when two different algorithms were used to sign a zone but only the
new set of keys are in the zone DNSKEY RRset.
[RT #22309] [CVE-2010-3614] [VU#837744]
</li></ul></div>
</div>
</div>
<div class="section" title="Bug Fixes"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="id36112186"></a>Bug Fixes</h2></div></div></div>
<div class="section" title="9.6-ESV-R2"><div class="titlepage"><div><div><h3 class="title"><a id="id36112191"></a>9.6-ESV-R2</h3></div></div></div>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
Check that named successfully skips NSEC3 records
that fail to match the NSEC3PARAM record currently
in use.
[RT #21868]
</li><li class="listitem">
Worked around a race condition in the cache database memory
handling. Without this fix a DNS cache DB or ADB could
incorrectly stay in an over memory state, effectively refusing
further caching, which subsequently made a BIND 9 caching
server unworkable.
[RT #21818]
</li><li class="listitem">
BIND did not properly handle non-cacheable negative responses
from insecure zones. This caused several non-protocol-compliant
zones to become unresolvable. BIND is now more accepting of
responses it receives from less strict servers.
[RT #21555]
</li><li class="listitem">
The resolver could attempt to destroy a fetch context too
soon, resulting in a crash.
[RT #19878]
</li><li class="listitem">
The placeholder negative caching element was not
properly constructed triggering a crash (INSIST) in
dns_ncache_towire().
[RT #21346]
</li><li class="listitem">
Handle the introduction of new trusted-keys and
DS, DLV RRsets better.
[RT #21097]
</li><li class="listitem">
Fix arguments to dns_keytable_findnextkeynode() call.
[RT #20877]
</li></ul></div>
</div>
<div class="section" title="9.6-ESV-R3"><div class="titlepage"><div><div><h3 class="title"><a id="id36112232"></a>9.6-ESV-R3</h3></div></div></div>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
Microsoft changed the behavior of sockets between NT/XP based
stacks vs Vista/windows7 stacks. Server 2003/2008 have the older
behavior, 2008r2 has the new behavior. With the change, different
error results are possible, so ISC adapted BIND to handle the new
error results.
This resolves an issue where sockets would shut down on
Windows servers causing named to stop responding to queries.
[RT #21906]
</li><li class="listitem">
Windows has non-POSIX compliant behavior in its rename() and unlink()
calls. This caused journal compaction to fail on Windows BIND servers
with the log error: "dns_journal_compact failed: failure".
[RT #22434]
</li><li class="listitem">
'host -D' now turns on debugging messages earlier.
[RT #22361]
</li><li class="listitem">
isc_print_vsnprintf() failed to check if there was
space available in the buffer when adding a left
justified character with a non zero width,
(e.g. "%-1c").
[RT #22270]
</li><li class="listitem">
view-&gt;queryacl was being overloaded. Seperate the
usage into view-&gt;queryacl, view-&gt;cacheacl and
view-&gt;queryonacl.
[RT #22114]
</li><li class="listitem">
win32: add more dependencies to BINDBuild.dsw.
[RT #22062]
</li><li class="listitem">
win32: named-checkzone and named-checkconf failed
to initialise winsock.
[RT #21932]
</li><li class="listitem">
named failed to generate a correct signed response
in a optout, delegation only zone with no secure
delegations.
[RT #22007]
</li></ul></div>
</div>
</div>
<div class="section" title="Known issues in this release"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="id36112280"></a>Known issues in this release</h2></div></div></div>
<div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem">
<p>
"make test" will fail on OSX and possibly other operating systems.
The failure occurs in a new test to check for allow-query ACLs.
The failure is caused because the source address is not specified on
the dig commands issued in the test.
</p>
<p>
If running "make test" is part of your usual acceptance process,
please edit the file <code class="code">bin/tests/system/allow_query/test.sh</code>
and add
</p><p>
<code class="code">-b 10.53.0.2</code>
</p><p>
to the <code class="code">DIGOPTS</code> line.
</p>
</li></ul></div>
</div>
<div class="section" title="Thank You"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="id36112315"></a>Thank You</h2></div></div></div>
<p>
Thank you to everyone who assisted us in making this release possible.
If you would like to contribute to ISC to assist us in continuing to make
quality open source software, please visit our donations page at
<a class="ulink" href="http://www.isc.org/supportisc" target="_top">http://www.isc.org/supportisc</a>.
</p>
</div>
</div></body></html>

Binary file not shown.

View File

@ -0,0 +1,133 @@
__________________________________________________________________
Introduction
BIND 9.6-ESV-R3 is a maintenance release for BIND 9.6-ESV.
This document summarizes changes from BIND 9.6-ESV-R1 to BIND
9.6-ESV-R3. Please see the CHANGES file in the source code release for
a complete list of all changes.
Download
The latest release of BIND 9 software can always be found on our web
site at http://www.isc.org/software/bind. There you will find
additional information about each release, source code, and some
pre-compiled versions for certain operating systems.
Support
Product support information is available on
http://www.isc.org/services/support for paid support options. Free
support is provided by our user community via a mailing list.
Information on all public email lists is available at
https://lists.isc.org/mailman/listinfo.
New Features
9.6-ESV-R2
None.
9.6-ESV-R3
None.
Feature Changes
9.6-ESV-R2
None.
9.6-ESV-R3
None.
Security Fixes
9.6-ESV-R2
None.
9.6-ESV-R3
* Adding a NO DATA signed negative response to cache failed to clear
any matching RRSIG records already in cache. A subsequent lookup of
the cached NO DATA entry could crash named (INSIST) when the
unexpected RRSIG was also returned with the NO DATA cache entry.
[RT #22288] [CVE-2010-3613] [VU#706148]
* BIND, acting as a DNSSEC validator, was determining if the NS RRset
is insecure based on a value that could mean either that the RRset
is actually insecure or that there wasn't a matching key for the
RRSIG in the DNSKEY RRset when resuming from validating the DNSKEY
RRset. This can happen when in the middle of a DNSKEY algorithm
rollover, when two different algorithms were used to sign a zone
but only the new set of keys are in the zone DNSKEY RRset. [RT
#22309] [CVE-2010-3614] [VU#837744]
Bug Fixes
9.6-ESV-R2
* Check that named successfully skips NSEC3 records that fail to
match the NSEC3PARAM record currently in use. [RT #21868]
* Worked around a race condition in the cache database memory
handling. Without this fix a DNS cache DB or ADB could incorrectly
stay in an over memory state, effectively refusing further caching,
which subsequently made a BIND 9 caching server unworkable. [RT
#21818]
* BIND did not properly handle non-cacheable negative responses from
insecure zones. This caused several non-protocol-compliant zones to
become unresolvable. BIND is now more accepting of responses it
receives from less strict servers. [RT #21555]
* The resolver could attempt to destroy a fetch context too soon,
resulting in a crash. [RT #19878]
* The placeholder negative caching element was not properly
constructed triggering a crash (INSIST) in dns_ncache_towire(). [RT
#21346]
* Handle the introduction of new trusted-keys and DS, DLV RRsets
better. [RT #21097]
* Fix arguments to dns_keytable_findnextkeynode() call. [RT #20877]
9.6-ESV-R3
* Microsoft changed the behavior of sockets between NT/XP based
stacks vs Vista/windows7 stacks. Server 2003/2008 have the older
behavior, 2008r2 has the new behavior. With the change, different
error results are possible, so ISC adapted BIND to handle the new
error results. This resolves an issue where sockets would shut down
on Windows servers causing named to stop responding to queries. [RT
#21906]
* Windows has non-POSIX compliant behavior in its rename() and
unlink() calls. This caused journal compaction to fail on Windows
BIND servers with the log error: "dns_journal_compact failed:
failure". [RT #22434]
* 'host -D' now turns on debugging messages earlier. [RT #22361]
* isc_print_vsnprintf() failed to check if there was space available
in the buffer when adding a left justified character with a non
zero width, (e.g. "%-1c"). [RT #22270]
* view->queryacl was being overloaded. Seperate the usage into
view->queryacl, view->cacheacl and view->queryonacl. [RT #22114]
* win32: add more dependencies to BINDBuild.dsw. [RT #22062]
* win32: named-checkzone and named-checkconf failed to initialise
winsock. [RT #21932]
* named failed to generate a correct signed response in a optout,
delegation only zone with no secure delegations. [RT #22007]
Known issues in this release
* "make test" will fail on OSX and possibly other operating systems.
The failure occurs in a new test to check for allow-query ACLs. The
failure is caused because the source address is not specified on
the dig commands issued in the test.
If running "make test" is part of your usual acceptance process,
please edit the file bin/tests/system/allow_query/test.sh and add
-b 10.53.0.2
to the DIGOPTS line.
Thank You
Thank you to everyone who assisted us in making this release possible.
If you would like to contribute to ISC to assist us in continuing to
make quality open source software, please visit our donations page at
http://www.isc.org/supportisc.

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: check-tool.c,v 1.35.36.3 2009/01/20 02:03:18 marka Exp $ */
/* $Id: check-tool.c,v 1.35.36.3.24.2 2010/09/07 23:46:25 tbox Exp $ */
/*! \file */
@ -23,6 +23,10 @@
#include <stdio.h>
#ifdef _WIN32
#include <Winsock2.h>
#endif
#include "check-tool.h"
#include <isc/buffer.h>
#include <isc/log.h>
@ -662,3 +666,26 @@ dump_zone(const char *zonename, dns_zone_t *zone, const char *filename,
return (result);
}
#ifdef _WIN32
void
InitSockets(void) {
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 0);
err = WSAStartup( wVersionRequested, &wsaData );
if (err != 0) {
fprintf(stderr, "WSAStartup() failed: %d\n", err);
exit(1);
}
}
void
DestroySockets(void) {
WSACleanup();
}
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2004, 2005, 2007, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: check-tool.h,v 1.14 2007/06/18 23:47:17 tbox Exp $ */
/* $Id: check-tool.h,v 1.14.628.2 2010/09/07 23:46:26 tbox Exp $ */
#ifndef CHECK_TOOL_H
#define CHECK_TOOL_H
@ -43,6 +43,11 @@ isc_result_t
dump_zone(const char *zonename, dns_zone_t *zone, const char *filename,
dns_masterformat_t fileformat, const dns_master_style_t *style);
#ifdef _WIN32
void InitSockets(void);
void DestroySockets(void);
#endif
extern int debug;
extern isc_boolean_t nomerge;
extern isc_boolean_t docheckmx;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2004-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: named-checkconf.c,v 1.46.222.2 2009/02/16 23:47:15 tbox Exp $ */
/* $Id: named-checkconf.c,v 1.46.222.2.24.2 2010/09/07 23:46:26 tbox Exp $ */
/*! \file */
@ -453,6 +453,10 @@ main(int argc, char **argv) {
if (conffile == NULL || conffile[0] == '\0')
conffile = NAMED_CONFFILE;
#ifdef _WIN32
InitSockets();
#endif
RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
RUNTIME_CHECK(setup_logging(mctx, stdout, &logc) == ISC_R_SUCCESS);
@ -494,5 +498,9 @@ main(int argc, char **argv) {
isc_mem_destroy(&mctx);
#ifdef _WIN32
DestroySockets();
#endif
return (exit_status);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: named-checkzone.c,v 1.51.34.4 2009/11/10 20:01:41 each Exp $ */
/* $Id: named-checkzone.c,v 1.51.34.4.10.2 2010/09/07 23:46:26 tbox Exp $ */
/*! \file */
@ -419,6 +419,10 @@ main(int argc, char **argv) {
if (isc_commandline_index + 2 != argc)
usage();
#ifdef _WIN32
InitSockets();
#endif
RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);
if (!quiet)
RUNTIME_CHECK(setup_logging(mctx, errout, &lctx)
@ -453,5 +457,8 @@ main(int argc, char **argv) {
isc_hash_destroy();
isc_entropy_detach(&ectx);
isc_mem_destroy(&mctx);
#ifdef _WIN32
DestroySockets();
#endif
return ((result == ISC_R_SUCCESS) ? 0 : 1);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2004-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: host.c,v 1.116.216.3 2009/09/08 23:28:20 marka Exp $ */
/* $Id: host.c,v 1.116.216.3.10.2 2010/10/19 23:46:25 tbox Exp $ */
/*! \file */
@ -625,7 +625,9 @@ pre_parse_args(int argc, char **argv) {
case 'v': break;
case 'w': break;
case 'C': break;
case 'D': break;
case 'D':
debugging = ISC_TRUE;
break;
case 'N': break;
case 'R': break;
case 'T': break;
@ -792,7 +794,7 @@ parse_args(isc_boolean_t is_batchfile, int argc, char **argv) {
ndots = atoi(isc_commandline_argument);
break;
case 'D':
debugging = ISC_TRUE;
/* Handled by pre_parse_args(). */
break;
case '4':
if (have_ipv4) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: client.c,v 1.259.12.3 2009/01/29 22:40:33 jinmei Exp $ */
/* $Id: client.c,v 1.259.12.3.24.2 2010/09/29 23:46:31 tbox Exp $ */
#include <config.h>
@ -1859,13 +1859,13 @@ client_request(isc_task_t *task, isc_event_t *event) {
client->view->recursionacl,
ISC_TRUE) == ISC_R_SUCCESS &&
ns_client_checkaclsilent(client, NULL,
client->view->queryacl,
client->view->cacheacl,
ISC_TRUE) == ISC_R_SUCCESS &&
ns_client_checkaclsilent(client, &client->interface->addr,
client->view->recursiononacl,
ISC_TRUE) == ISC_R_SUCCESS &&
ns_client_checkaclsilent(client, &client->interface->addr,
client->view->queryonacl,
client->view->cacheonacl,
ISC_TRUE) == ISC_R_SUCCESS)
ra = ISC_TRUE;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2004, 2005, 2007, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: query.h,v 1.40 2007/06/19 23:46:59 tbox Exp $ */
/* $Id: query.h,v 1.40.626.2 2010/09/29 23:46:31 tbox Exp $ */
#ifndef NAMED_QUERY_H
#define NAMED_QUERY_H 1
@ -71,6 +71,8 @@ struct ns_query {
#define NS_QUERYATTR_SECURE 0x0200
#define NS_QUERYATTR_NOAUTHORITY 0x0400
#define NS_QUERYATTR_NOADDITIONAL 0x0800
#define NS_QUERYATTR_CACHEACLOKVALID 0x1000
#define NS_QUERYATTR_CACHEACLOK 0x2000
isc_result_t
ns_query_init(ns_client_t *client);

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: query.c,v 1.313.20.16.10.2 2010/06/26 23:46:14 tbox Exp $ */
/* $Id: query.c,v 1.313.20.16.10.3 2010/09/29 00:03:32 marka Exp $ */
/*! \file */
@ -820,17 +820,15 @@ query_getcachedb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype,
return (DNS_R_REFUSED);
dns_db_attach(client->view->cachedb, &db);
if ((client->query.attributes &
NS_QUERYATTR_QUERYOKVALID) != 0) {
if ((client->query.attributes & NS_QUERYATTR_CACHEACLOKVALID) != 0) {
/*
* We've evaluated the view's queryacl already. If
* NS_QUERYATTR_QUERYOK is set, then the client is
* We've evaluated the view's cacheacl already. If
* NS_QUERYATTR_CACHEACLOK is set, then the client is
* allowed to make queries, otherwise the query should
* be refused.
*/
check_acl = ISC_FALSE;
if ((client->query.attributes &
NS_QUERYATTR_QUERYOK) == 0)
if ((client->query.attributes & NS_QUERYATTR_CACHEACLOK) == 0)
goto refuse;
} else {
/*
@ -844,16 +842,15 @@ query_getcachedb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype,
char msg[NS_CLIENT_ACLMSGSIZE("query (cache)")];
result = ns_client_checkaclsilent(client, NULL,
client->view->queryacl,
client->view->cacheacl,
ISC_TRUE);
if (result == ISC_R_SUCCESS) {
/*
* We were allowed by the default
* "allow-query" ACL. Remember this so we
* don't have to check again.
* We were allowed by the "allow-query-cache" ACL.
* Remember this so we don't have to check again.
*/
client->query.attributes |=
NS_QUERYATTR_QUERYOK;
NS_QUERYATTR_CACHEACLOK;
if (log && isc_log_wouldlog(ns_g_lctx,
ISC_LOG_DEBUG(3)))
{
@ -876,9 +873,9 @@ query_getcachedb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype,
}
/*
* We've now evaluated the view's query ACL, and
* the NS_QUERYATTR_QUERYOK attribute is now valid.
* the NS_QUERYATTR_CACHEACLOKVALID attribute is now valid.
*/
client->query.attributes |= NS_QUERYATTR_QUERYOKVALID;
client->query.attributes |= NS_QUERYATTR_CACHEACLOKVALID;
if (result != ISC_R_SUCCESS)
goto refuse;

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: server.c,v 1.520.12.11.10.1 2010/03/03 22:06:36 marka Exp $ */
/* $Id: server.c,v 1.520.12.11.10.4 2010/11/16 22:42:03 marka Exp $ */
/*! \file */
@ -1132,6 +1132,14 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
dns_acache_setcachesize(view->acache, max_acache_size);
}
CHECK(configure_view_acl(vconfig, config, "allow-query", actx,
ns_g_mctx, &view->queryacl));
if (view->queryacl == NULL) {
CHECK(configure_view_acl(NULL, ns_g_config, "allow-query", actx,
ns_g_mctx, &view->queryacl));
}
/*
* Configure the zones.
*/
@ -1606,13 +1614,13 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
* configured in named.conf.
*/
CHECK(configure_view_acl(vconfig, config, "allow-query-cache",
actx, ns_g_mctx, &view->queryacl));
actx, ns_g_mctx, &view->cacheacl));
CHECK(configure_view_acl(vconfig, config, "allow-query-cache-on",
actx, ns_g_mctx, &view->queryonacl));
if (view->queryonacl == NULL)
actx, ns_g_mctx, &view->cacheonacl));
if (view->cacheonacl == NULL)
CHECK(configure_view_acl(NULL, ns_g_config,
"allow-query-cache-on", actx,
ns_g_mctx, &view->queryonacl));
ns_g_mctx, &view->cacheonacl));
if (strcmp(view->name, "_bind") != 0) {
CHECK(configure_view_acl(vconfig, config, "allow-recursion",
actx, ns_g_mctx,
@ -1628,14 +1636,14 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
* "allow-recursion" inherits from "allow-query-cache" if set,
* otherwise from "allow-query" if set.
*/
if (view->queryacl == NULL && view->recursionacl != NULL)
dns_acl_attach(view->recursionacl, &view->queryacl);
if (view->queryacl == NULL && view->recursion)
if (view->cacheacl == NULL && view->recursionacl != NULL)
dns_acl_attach(view->recursionacl, &view->cacheacl);
if (view->cacheacl == NULL && view->recursion)
CHECK(configure_view_acl(vconfig, config, "allow-query",
actx, ns_g_mctx, &view->queryacl));
actx, ns_g_mctx, &view->cacheacl));
if (view->recursion &&
view->recursionacl == NULL && view->queryacl != NULL)
dns_acl_attach(view->queryacl, &view->recursionacl);
view->recursionacl == NULL && view->cacheacl != NULL)
dns_acl_attach(view->cacheacl, &view->recursionacl);
/*
* Set default "allow-recursion", "allow-recursion-on" and
@ -1651,16 +1659,13 @@ configure_view(dns_view_t *view, const cfg_obj_t *config,
"allow-recursion-on",
actx, ns_g_mctx,
&view->recursiononacl));
if (view->queryacl == NULL) {
if (view->cacheacl == NULL) {
if (view->recursion)
CHECK(configure_view_acl(NULL, ns_g_config,
"allow-query-cache", actx,
ns_g_mctx, &view->queryacl));
else {
if (view->queryacl != NULL)
dns_acl_detach(&view->queryacl);
CHECK(dns_acl_none(ns_g_mctx, &view->queryacl));
}
ns_g_mctx, &view->cacheacl));
else
CHECK(dns_acl_none(ns_g_mctx, &view->cacheacl));
}
/*

View File

@ -1,3 +1,3 @@
LIBINTERFACE = 57
LIBINTERFACE = 58
LIBREVISION = 0
LIBAGE = 2
LIBAGE = 0

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: view.h,v 1.111.88.4 2009/01/29 22:40:35 jinmei Exp $ */
/* $Id: view.h,v 1.111.88.4.24.2 2010/09/29 23:46:31 tbox Exp $ */
#ifndef DNS_VIEW_H
#define DNS_VIEW_H 1
@ -118,6 +118,8 @@ struct dns_view {
isc_boolean_t enablevalidation;
isc_boolean_t acceptexpired;
dns_transfer_format_t transfer_format;
dns_acl_t * cacheacl;
dns_acl_t * cacheonacl;
dns_acl_t * queryacl;
dns_acl_t * queryonacl;
dns_acl_t * recursionacl;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2004, 2005, 2007-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: journal.c,v 1.103.48.6 2009/11/04 23:47:25 tbox Exp $ */
/* $Id: journal.c,v 1.103.48.6.10.2 2010/11/17 23:46:16 tbox Exp $ */
#include <config.h>
@ -2173,6 +2173,12 @@ dns_journal_compact(isc_mem_t *mctx, char *filename, isc_uint32_t serial,
indexend = new->header.end.offset;
}
/*
* Close both journals before trying to rename files (this is
* necessary on WIN32).
*/
dns_journal_destroy(&j);
dns_journal_destroy(&new);
/*
@ -2180,12 +2186,14 @@ dns_journal_compact(isc_mem_t *mctx, char *filename, isc_uint32_t serial,
* Any IXFR outs will just continue and the old journal will be
* removed on final close.
*
* With MSDOS / NTFS we need to do a two stage rename triggered
* bu EEXISTS. Hopefully all IXFR's that were active at the last
* rename are now complete.
* With MSDOS / NTFS we need to do a two stage rename, triggered
* by EEXIST. (If any IXFR's are running in other threads, however,
* this will fail, and the journal will not be compacted. But
* if so, hopefully they'll be finished by the next time we
* compact.)
*/
if (rename(newname, filename) == -1) {
if (errno == EACCES && !is_backup) {
if (errno == EEXIST && !is_backup) {
result = isc_file_remove(backup);
if (result != ISC_R_SUCCESS &&
result != ISC_R_FILENOTFOUND)
@ -2202,7 +2210,6 @@ dns_journal_compact(isc_mem_t *mctx, char *filename, isc_uint32_t serial,
}
}
dns_journal_destroy(&j);
result = ISC_R_SUCCESS;
failure:

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rbtdb.c,v 1.270.12.16.10.3 2010/08/13 07:25:21 marka Exp $ */
/* $Id: rbtdb.c,v 1.270.12.16.10.6 2010/11/16 07:46:23 marka Exp $ */
/*! \file */
@ -5421,14 +5421,14 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
dns_rdataset_t *addedrdataset, isc_stdtime_t now)
{
rbtdb_changed_t *changed = NULL;
rdatasetheader_t *topheader, *topheader_prev, *header;
rdatasetheader_t *topheader, *topheader_prev, *header, *sigheader;
unsigned char *merged;
isc_result_t result;
isc_boolean_t header_nx;
isc_boolean_t newheader_nx;
isc_boolean_t merge;
dns_rdatatype_t rdtype, covers;
rbtdb_rdatatype_t negtype;
rbtdb_rdatatype_t negtype, sigtype;
dns_trust_t trust;
int idx;
@ -5466,7 +5466,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
newheader_nx = NONEXISTENT(newheader) ? ISC_TRUE : ISC_FALSE;
topheader_prev = NULL;
sigheader = NULL;
negtype = 0;
if (rbtversion == NULL && !newheader_nx) {
rdtype = RBTDB_RDATATYPE_BASE(newheader->type);
@ -5475,26 +5475,34 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
* We're adding a negative cache entry.
*/
covers = RBTDB_RDATATYPE_EXT(newheader->type);
if (covers == dns_rdatatype_any) {
sigtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig,
covers);
for (topheader = rbtnode->data;
topheader != NULL;
topheader = topheader->next) {
/*
* We're adding an negative cache entry
* If we're adding an negative cache entry
* which covers all types (NXDOMAIN,
* NODATA(QTYPE=ANY)).
*
* We make all other data stale so that the
* only rdataset that can be found at this
* node is the negative cache entry.
*
* Otherwise look for any RRSIGs of the
* given type so they can be marked stale
* later.
*/
for (topheader = rbtnode->data;
topheader != NULL;
topheader = topheader->next) {
if (covers == dns_rdatatype_any) {
set_ttl(rbtdb, topheader, 0);
topheader->attributes |=
RDATASET_ATTR_STALE;
}
rbtnode->dirty = 1;
goto find_header;
rbtnode->dirty = 1;
} else if (topheader->type == sigtype)
sigheader = topheader;
}
if (covers == dns_rdatatype_any)
goto find_header;
negtype = RBTDB_RDATATYPE_VALUE(covers, 0);
} else {
/*
@ -5732,6 +5740,11 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
if (rbtversion == NULL) {
set_ttl(rbtdb, header, 0);
header->attributes |= RDATASET_ATTR_STALE;
if (sigheader != NULL) {
set_ttl(rbtdb, sigheader, 0);
sigheader->attributes |=
RDATASET_ATTR_STALE;
}
}
idx = newheader->node->locknum;
if (IS_CACHE(rbtdb)) {
@ -7071,6 +7084,8 @@ dns_rbtdb_create
* change.
*/
if (!IS_CACHE(rbtdb)) {
dns_rbtnode_t *nsec3node;
rbtdb->origin_node = NULL;
result = dns_rbt_addnode(rbtdb->tree, &rbtdb->common.origin,
&rbtdb->origin_node);
@ -7093,6 +7108,32 @@ dns_rbtdb_create
rbtdb->origin_node->locknum =
dns_name_hash(&name, ISC_TRUE) %
rbtdb->node_lock_count;
#endif
/*
* Add an apex node to the NSEC3 tree so that NSEC3 searches
* return partial matches when there is only a single NSEC3
* record in the tree.
*/
nsec3node = NULL;
result = dns_rbt_addnode(rbtdb->nsec3, &rbtdb->common.origin,
&nsec3node);
if (result != ISC_R_SUCCESS) {
INSIST(result != ISC_R_EXISTS);
free_rbtdb(rbtdb, ISC_FALSE, NULL);
return (result);
}
nsec3node->nsec3 = 1;
/*
* We need to give the nsec3 origin node the right locknum.
*/
dns_name_init(&name, NULL);
dns_rbt_namefromnode(nsec3node, &name);
#ifdef DNS_RBT_USEHASH
nsec3node->locknum = nsec3node->hashval %
rbtdb->node_lock_count;
#else
nsec3node->locknum = dns_name_hash(&name, ISC_TRUE) %
rbtdb->node_lock_count;
#endif
}

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: validator.c,v 1.164.12.11.10.6 2010/09/03 02:55:18 marka Exp $ */
/* $Id: validator.c,v 1.164.12.11.10.7 2010/11/16 01:48:32 marka Exp $ */
#include <config.h>
@ -393,6 +393,7 @@ fetch_callback_validator(isc_task_t *task, isc_event_t *event) {
isc_boolean_t want_destroy;
isc_result_t result;
isc_result_t eresult;
isc_result_t saved_result;
UNUSED(task);
INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
@ -429,6 +430,17 @@ fetch_callback_validator(isc_task_t *task, isc_event_t *event) {
val->keyset = &val->frdataset;
}
result = validate(val, ISC_TRUE);
if (result == DNS_R_NOVALIDSIG &&
(val->attributes & VALATTR_TRIEDVERIFY) == 0)
{
saved_result = result;
validator_log(val, ISC_LOG_DEBUG(3),
"falling back to insecurity proof");
val->attributes |= VALATTR_INSECURITY;
result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
if (result == DNS_R_NOTINSECURE)
result = saved_result;
}
if (result != DNS_R_WAIT)
validator_done(val, result);
} else {
@ -619,6 +631,7 @@ keyvalidated(isc_task_t *task, isc_event_t *event) {
isc_boolean_t want_destroy;
isc_result_t result;
isc_result_t eresult;
isc_result_t saved_result;
UNUSED(task);
INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
@ -645,6 +658,17 @@ keyvalidated(isc_task_t *task, isc_event_t *event) {
if (val->frdataset.trust >= dns_trust_secure)
(void) get_dst_key(val, val->siginfo, &val->frdataset);
result = validate(val, ISC_TRUE);
if (result == DNS_R_NOVALIDSIG &&
(val->attributes & VALATTR_TRIEDVERIFY) == 0)
{
saved_result = result;
validator_log(val, ISC_LOG_DEBUG(3),
"falling back to insecurity proof");
val->attributes |= VALATTR_INSECURITY;
result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
if (result == DNS_R_NOTINSECURE)
result = saved_result;
}
if (result != DNS_R_WAIT)
validator_done(val, result);
} else {
@ -1875,9 +1899,11 @@ validate(dns_validator_t *val, isc_boolean_t resume) {
* was known and "sufficiently good".
*/
if (!dns_resolver_algorithm_supported(val->view->resolver,
event->name,
val->siginfo->algorithm))
event->name,
val->siginfo->algorithm)) {
resume = ISC_FALSE;
continue;
}
if (!resume) {
result = get_key(val, val->siginfo);
@ -1888,16 +1914,12 @@ validate(dns_validator_t *val, isc_boolean_t resume) {
}
/*
* The key is insecure, so mark the data as insecure also.
* There isn't a secure DNSKEY for this signature so move
* onto the next RRSIG.
*/
if (val->key == NULL) {
if (val->mustbesecure) {
validator_log(val, ISC_LOG_WARNING,
"must be secure failure");
return (DNS_R_MUSTBESECURE);
}
markanswer(val, "validate");
return (ISC_R_SUCCESS);
resume = ISC_FALSE;
continue;
}
do {
@ -3703,6 +3725,20 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
*/
result = DNS_R_NOVALIDNSEC;
goto out;
} else if (DNS_TRUST_PENDING(val->frdataset.trust) ||
DNS_TRUST_ANSWER(val->frdataset.trust)) {
/*
* If we have "trust == answer" then this namespace
* has switched from insecure to should be secure.
*/
result = create_validator(val, tname,
dns_rdatatype_ds,
&val->frdataset,
NULL, dsvalidated,
"proveunsecure");
if (result != ISC_R_SUCCESS)
goto out;
return (DNS_R_WAIT);
} else if (val->frdataset.trust < dns_trust_secure) {
/*
* This shouldn't happen, since the negative

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: view.c,v 1.150.84.3.10.1 2010/03/03 22:06:39 marka Exp $ */
/* $Id: view.c,v 1.150.84.3.10.2 2010/09/29 00:03:32 marka Exp $ */
/*! \file */
@ -168,6 +168,8 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
view->acceptexpired = ISC_FALSE;
view->minimalresponses = ISC_FALSE;
view->transfer_format = dns_one_answer;
view->cacheacl = NULL;
view->cacheonacl = NULL;
view->queryacl = NULL;
view->queryonacl = NULL;
view->recursionacl = NULL;
@ -294,6 +296,10 @@ destroy(dns_view_t *view) {
dns_acl_detach(&view->matchclients);
if (view->matchdestinations != NULL)
dns_acl_detach(&view->matchdestinations);
if (view->cacheacl != NULL)
dns_acl_detach(&view->cacheacl);
if (view->cacheonacl != NULL)
dns_acl_detach(&view->cacheonacl);
if (view->queryacl != NULL)
dns_acl_detach(&view->queryacl);
if (view->queryonacl != NULL)

View File

@ -1,3 +1,3 @@
LIBINTERFACE = 53
LIBREVISION = 0
LIBREVISION = 1
LIBAGE = 3

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: print.c,v 1.35 2008/02/18 23:46:59 tbox Exp $ */
/* $Id: print.c,v 1.35.418.2 2010/10/18 23:46:34 tbox Exp $ */
/*! \file */
@ -468,7 +468,7 @@ isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
if (width > 0) {
count += width;
width--;
if (left) {
if (left && size > 1) {
*str++ = c;
size--;
}

View File

@ -0,0 +1,60 @@
/*
* Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC 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.
*/
/* $Id: release-notes.css,v 1.1.4.3 2010/11/29 01:16:39 tbox Exp $ */
body {
background-color: #ffffff;
color: #333333;
font-family: "Helvetica Neue", "ArialMT", "Verdana", "Arial", "Helvetica", sans-serif;
font-size: 14px;
line-height: 18px;
margin: 2em auto;
width: 700px;
}
.command {
font-family: "Courier New", "Courier", monospace;
font-weight: normal;
}
.note {
background-color: #ddeedd;
border: 1px solid #aaccaa;
margin: 1em 0 1em 0;
padding: 0.5em 1em 0.5em 1em;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
}
.screen {
background-color: #ffffee;
border: 1px solid #ddddaa;
padding: 0.25em 1em 0.25em 1em;
margin: 1em 0 1em 0;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
}
.section.title {
font-size: 150%;
font-weight: bold;
}
.section.section.title {
font-size: 130%;
font-weight: bold;
}

View File

@ -1,4 +1,4 @@
# $Id: version,v 1.43.12.8.4.3 2010/09/03 02:57:11 marka Exp $
# $Id: version,v 1.43.12.8.4.4 2010/11/18 23:37:13 marka Exp $
#
# This file must follow /bin/sh rules. It is imported directly via
# configure.
@ -7,4 +7,4 @@ MAJORVER=9
MINORVER=6
PATCHVER=
RELEASETYPE=-ESV
RELEASEVER=-R2
RELEASEVER=-R3

View File

@ -196,7 +196,7 @@ asn_put_temp_header(struct asn_buf *b, u_char type, u_char **ptr)
return (ret);
}
enum asn_err
asn_commit_header(struct asn_buf *b, u_char *ptr)
asn_commit_header(struct asn_buf *b, u_char *ptr, size_t *moved)
{
asn_len_t len;
u_int lenlen, shift;
@ -215,6 +215,8 @@ asn_commit_header(struct asn_buf *b, u_char *ptr)
memmove(ptr + 1 + lenlen, ptr + TEMP_LEN, len);
b->asn_ptr -= shift;
b->asn_len += shift;
if (moved != NULL)
*moved = shift;
}
return (ASN_ERR_OK);
}
@ -912,6 +914,20 @@ asn_skip(struct asn_buf *b, asn_len_t len)
return (ASN_ERR_OK);
}
/*
* Add a padding
*/
enum asn_err
asn_pad(struct asn_buf *b, asn_len_t len)
{
if (b->asn_len < len)
return (ASN_ERR_EOBUF);
b->asn_ptr += len;
b->asn_len -= len;
return (ASN_ERR_OK);
}
/*
* Compare two OIDs.
*

View File

@ -93,7 +93,7 @@ enum asn_err asn_get_header(struct asn_buf *, u_char *, asn_len_t *);
enum asn_err asn_put_header(struct asn_buf *, u_char, asn_len_t);
enum asn_err asn_put_temp_header(struct asn_buf *, u_char, u_char **);
enum asn_err asn_commit_header(struct asn_buf *, u_char *);
enum asn_err asn_commit_header(struct asn_buf *, u_char *, size_t *);
enum asn_err asn_get_integer_raw(struct asn_buf *, asn_len_t, int32_t *);
enum asn_err asn_get_integer(struct asn_buf *, int32_t *);
@ -129,6 +129,7 @@ enum asn_err asn_get_timeticks(struct asn_buf *, uint32_t *);
enum asn_err asn_put_timeticks(struct asn_buf *, uint32_t);
enum asn_err asn_skip(struct asn_buf *, asn_len_t);
enum asn_err asn_pad(struct asn_buf *, asn_len_t);
/*
* Utility functions for OIDs

View File

@ -31,7 +31,7 @@
.\"
.\" $Begemot: bsnmp/lib/bsnmpclient.3,v 1.12 2005/10/04 08:46:50 brandt_h Exp $
.\"
.Dd October 4, 2005
.Dd September 9, 2010
.Dt BSNMPCLIENT 3
.Os
.Sh NAME
@ -52,7 +52,8 @@
.Nm snmp_table_cb_f ,
.Nm snmp_table_fetch ,
.Nm snmp_table_fetch_async ,
.Nm snmp_dialog
.Nm snmp_dialog ,
.Nm snmp_discover_engine
.Nd "SNMP client library"
.Sh LIBRARY
Begemot SNMP library
@ -102,44 +103,56 @@ Begemot SNMP library
.Fn snmp_table_fetch_async "const struct snmp_table *descr" "void *list" "snmp_table_cb_f callback" "void *uarg"
.Ft int
.Fn snmp_dialog "struct snmp_pdu *req" "struct snmp_pdu *resp"
.Ft int
.Fn snmp_discover_engine "void"
.Sh DESCRIPTION
The SNMP library contains routines to easily build SNMP client applications
that use SNMP versions 1 or 2.
that use SNMP versions 1, 2 or 3.
Most of the routines use a
.Vt struct snmp_client :
.Bd -literal -offset indent
struct snmp_client {
enum snmp_version version;
int trans; /* transport type to use */
enum snmp_version version;
int trans; /* which transport to use */
/* these two are read-only for the application */
char *cport; /* port number as string */
char *chost; /* host name or IP address as string */
char *cport; /* port number as string */
char *chost; /* host name or IP address as string */
char read_community[SNMP_COMMUNITY_MAXLEN + 1];
char write_community[SNMP_COMMUNITY_MAXLEN + 1];
char read_community[SNMP_COMMUNITY_MAXLEN + 1];
char write_community[SNMP_COMMUNITY_MAXLEN + 1];
struct timeval timeout;
u_int retries;
/* SNMPv3 specific fields */
int32_t identifier;
int32_t security_model;
struct snmp_engine engine;
struct snmp_user user;
int dump_pdus;
/* SNMPv3 Access control - VACM*/
uint32_t clen;
uint8_t cengine[SNMP_ENGINE_ID_SIZ];
char cname[SNMP_CONTEXT_NAME_SIZ];
size_t txbuflen;
size_t rxbuflen;
struct timeval timeout;
u_int retries;
int fd;
int dump_pdus;
int32_t next_reqid;
int32_t max_reqid;
int32_t min_reqid;
size_t txbuflen;
size_t rxbuflen;
char error[SNMP_STRERROR_LEN];
int fd;
snmp_timeout_start_f timeout_start;
snmp_timeout_stop_f timeout_stop;
int32_t next_reqid;
int32_t max_reqid;
int32_t min_reqid;
/* private */
char local_path[sizeof(SNMP_LOCAL_PATH)];
char error[SNMP_STRERROR_LEN];
snmp_timeout_start_f timeout_start;
snmp_timeout_stop_f timeout_stop;
char local_path[sizeof(SNMP_LOCAL_PATH)];
};
.Ed
.Pp
@ -194,6 +207,23 @@ The default is
The community name to be used for SET requests.
The default is
.Sq private .
.It Va identifier
The message indentifier value to be used with SNMPv3 PDUs. Incremented with
each transmitted PDU.
.It Va security_model
The security model to be used with SNMPv3 PDUs. Currently only User-Based
Security model specified by RFC 3414 (value 3) is supported.
.It Va engine
The authorative SNMP engine parameters to be used with SNMPv3 PDUs.
.It Va user
The USM SNMP user credentials to be used with SNMPv3 PDUs.
.It Va clen
The length of the context engine id to be used with SNMPv3 PDUs.
.It Va cengine
The context engine id to be used with SNMPv3 PDUs. Default is empty.
.It Va cname
The context name to be used with SNMPv3 PDUs. Default is
.Sq "" .
.It Va timeout
The maximum time to wait for responses to requests.
If the time elapses, the request is resent up to
@ -617,6 +647,21 @@ returns -1.
If a response was received 0 is returned.
.Pp
The function
.Fn snmp_discover_engine
is used to discover the authorative snmpEngineId of a remote SNMPv3 agent.
A request PDU with empty USM user name is sent and the client's engine
parameters are set according to the snmpEngine parameters received in the
response PDU.
If the client is configured to use authentication and/or privacy and the
snmpEngineBoots and/or snmpEngineTime in the response had zero values, an
additional request (possibly encrypted) with the appropriate user credentials
is sent to fetch the missing values.
Note, that the function blocks until the discovery proccess is completed.
If no response could be received after all timeouts and retries, or the
response contained errors the function returns -1.
If the discovery proccess was completed 0 is returned.
.Pp
The function
.Fn snmp_parse_server
is used to parse an SNMP server specification string and fill in the
fields of a

View File

@ -1,4 +1,10 @@
.\"
.\" Copyright (c) 2010 The FreeBSD Foundation
.\" All rights reserved.
.\"
.\" Portions of this documentation were written by Shteryana Sotirova Shopova
.\" under sponsorship from the FreeBSD Foundation.
.\"
.\" Copyright (c) 2004-2005
.\" Hartmut Brandt.
.\" All rights reserved.
@ -31,7 +37,7 @@
.\"
.\" $Begemot: bsnmp/lib/bsnmplib.3,v 1.9 2005/10/04 08:46:51 brandt_h Exp $
.\"
.Dd October 4, 2005
.Dd September 9, 2010
.Dt BSNMPLIB 3
.Os
.Sh NAME
@ -39,9 +45,15 @@
.Nm snmp_value_parse ,
.Nm snmp_value_copy ,
.Nm snmp_pdu_free ,
.Nm snmp_code snmp_pdu_decode ,
.Nm snmp_code snmp_pdu_encode ,
.Nm snmp_pdu_decode ,
.Nm snmp_pdu_encode ,
.Nm snmp_pdu_decode_header ,
.Nm snmp_pdu_decode_scoped ,
.Nm snmp_pdu_decode_secmode ,
.Nm snmp_pdu_dump ,
.Nm snmp_passwd_to_keys ,
.Nm snmp_get_local_keys ,
.Nm snmp_calc_keychange ,
.Nm TRUTH_MK ,
.Nm TRUTH_GET ,
.Nm TRUTH_OK
@ -64,8 +76,20 @@ Begemot SNMP library
.Fn snmp_pdu_decode "struct asn_buf *buf" "struct snmp_pdu *pdu" "int32_t *ip"
.Ft enum snmp_code
.Fn snmp_pdu_encode "struct snmp_pdu *pdu" "struct asn_buf *buf"
.Ft enum snmp_code
.Fn snmp_pdu_decode_header "struct snmp_pdu *pdu" "struct asn_buf *buf"
.Ft enum snmp_code
.Fn snmp_pdu_decode_scoped "struct asn_buf *buf" "struct snmp_pdu *pdu" "int32_t *ip"
.Ft enum snmp_code
.Fn snmp_pdu_decode_secmode "struct asn_buf *buf" "struct snmp_pdu *pdu"
.Ft void
.Fn snmp_pdu_dump "const struct snmp_pdu *pdu"
.Ft enum snmp_code
.Fn snmp_passwd_to_keys "struct snmp_user *user" "char *passwd"
.Ft enum snmp_code
.Fn snmp_get_local_keys "struct snmp_user *user" "uint8_t *eid" "uint32_t elen"
.Ft enum snmp_code
.Fn snmp_calc_keychange "struct snmp_user *user" "uint8_t *keychange"
.Ft int
.Fn TRUTH_MK "F"
.Ft int
@ -73,8 +97,8 @@ Begemot SNMP library
.Ft int
.Fn TRUTH_OK "T"
.Sh DESCRIPTION
The SNMP library contains routines to handle SNMP version 1 and 2 PDUs.
There are two basic structures used throughout the library:
The SNMP library contains routines to handle SNMP version 1, 2 and 3 PDUs.
There are several basic structures used throughout the library:
.Bd -literal -offset indent
struct snmp_value {
struct asn_oid var;
@ -134,34 +158,126 @@ is not zero,
.Fa v.octetstring.octets
points to a string allocated by
.Xr malloc 3 .
.Pp
.Bd -literal -offset indent
#define SNMP_COMMUNITY_MAXLEN 128
#define SNMP_MAX_BINDINGS 100
#define SNMP_ENGINE_ID_SIZ 32
struct snmp_engine {
uint8_t engine_id[SNMP_ENGINE_ID_SIZ];
uint32_t engine_len;
int32_t engine_boots;
int32_t engine_time;
int32_t max_msg_size;
};
.Ed
.Pp
This structure represents an SNMP engine as specified by the SNMP Management
Architecture described in RFC 3411.
.Pp
.Bd -literal -offset indent
#define SNMP_USM_NAME_SIZ (32 + 1)
#define SNMP_AUTH_KEY_SIZ 40
#define SNMP_PRIV_KEY_SIZ 32
struct snmp_user {
char sec_name[SNMP_USM_NAME_SIZ];
enum snmp_authentication auth_proto;
enum snmp_privacy priv_proto;
uint8_t auth_key[SNMP_AUTH_KEY_SIZ];
uint8_t priv_key[SNMP_PRIV_KEY_SIZ];
};
.Ed
.Pp
This structure represents an SNMPv3 user as specified by the User-based
Security Model (USM) described in RFC 3414. The field
.Fa sec_name
is a human readable string containing the security user name.
.Fa auth_proto
contains the id of the authentication protocol in use by the user and may be one
of:
.Bd -literal -offset indent
enum snmp_authentication {
SNMP_AUTH_NOAUTH = 0,
SNMP_AUTH_HMAC_MD5,
SNMP_AUTH_HMAC_SHA
};
.Ed
.Fa priv_proto
contains the id of the privacy protocol in use by the user and may be one
of:
.Bd -literal -offset indent
enum snmp_privacy {
SNMP_PRIV_NOPRIV = 0,
SNMP_PRIV_DES = 1,
SNMP_PRIV_AES
};
.Ed
.Fa auth_key
and
.Fa priv_key
contain the authentication and privacy keys for the user.
.Pp
.Bd -literal -offset indent
#define SNMP_COMMUNITY_MAXLEN 128
#define SNMP_MAX_BINDINGS 100
#define SNMP_CONTEXT_NAME_SIZ (32 + 1)
#define SNMP_TIME_WINDOW 150
#define SNMP_USM_AUTH_SIZE 12
#define SNMP_USM_PRIV_SIZE 8
#define SNMP_MSG_AUTH_FLAG 0x1
#define SNMP_MSG_PRIV_FLAG 0x2
#define SNMP_MSG_REPORT_FLAG 0x4
#define SNMP_SECMODEL_USM 3
struct snmp_pdu {
char community[SNMP_COMMUNITY_MAXLEN + 1];
enum snmp_version version;
u_int type;
char community[SNMP_COMMUNITY_MAXLEN + 1];
enum snmp_version version;
u_int type;
/* SNMPv3 PDU header fields */
int32_t identifier;
uint8_t flags;
int32_t security_model;
struct snmp_engine engine;
/* Associated USM user parameters */
struct snmp_user user;
uint8_t msg_digest[SNMP_USM_AUTH_SIZE];
uint8_t msg_salt[SNMP_USM_PRIV_SIZE];
/* View-based Access Model */
uint32_t context_engine_len;
uint8_t context_engine[SNMP_ENGINE_ID_SIZ];
char context_name[SNMP_CONTEXT_NAME_SIZ];
/* trap only */
struct asn_oid enterprise;
u_char agent_addr[4];
int32_t generic_trap;
int32_t specific_trap;
u_int32_t time_stamp;
struct asn_oid enterprise;
u_char agent_addr[4];
int32_t generic_trap;
int32_t specific_trap;
uint32_t time_stamp;
/* others */
int32_t request_id;
int32_t error_status;
int32_t error_index;
int32_t request_id;
int32_t error_status;
int32_t error_index;
/* fixes for encoding */
u_char *outer_ptr;
u_char *pdu_ptr;
u_char *vars_ptr;
size_t outer_len;
size_t scoped_len;
u_char *outer_ptr;
u_char *digest_ptr;
u_char *encrypted_ptr;
u_char *scoped_ptr;
u_char *pdu_ptr;
u_char *vars_ptr;
struct snmp_value bindings[SNMP_MAX_BINDINGS];
u_int nbindings;
struct snmp_value bindings[SNMP_MAX_BINDINGS];
u_int nbindings;
};
.Ed
This structure contains a decoded SNMP PDU.
@ -172,11 +288,15 @@ enum snmp_version {
SNMP_Verr = 0,
SNMP_V1 = 1,
SNMP_V2c,
SNMP_V3
};
.Ed
and
.Fa type
is the type of the PDU.
.Fa security_model
is the security model used for SNMPv3 PDUs. The only supported
value currently is 3 (User-based Security Model).
.Pp
The function
.Fn snmp_value_free
@ -223,15 +343,60 @@ The function
.Fn snmp_pdu_encode
encodes the PDU
.Fa pdu
into the an octetstring in buffer
into the an octetstring in buffer, and if authentication and privacy are used,
calculates a message digest and encrypts the PDU data in the buffer
.Fa buf .
.Pp
The function
.Fn snmp_pdu_decode_header
decodes the header of the PDU pointed to by
.Fa buf .
The uncoded PDU contents remain in the buffer.
.Pp
The function
.Fn snmp_pdu_decode_scoped
decodes the scoped PDU pointed to by
.Fa buf .
.Pp
The function
.Fn snmp_pdu_decode_secmode
verifies the authentication parameter contained in the PDU (if present) and
if the PDU is encrypted, decrypts the PDU contents pointed to by
.Fa buf .
If successfull, a plain text scoped PDU is stored in the buffer.
.Pp
The function
.Fn snmp_pdu_dump
dumps the PDU in a human readable form by calling
.Fn snmp_printf .
.Pp
The function
.Fn snmp_passwd_to_keys
calculates a binary private authentication key corresponding to a plain text human
readable password string. The calculated key is placed in the
.Fa auth_key
field of the
.Fa user .
.Pp
The function
.Fn snmp_get_local_keys
calculates a localazied authentication and privacy keys for a specified SNMPv3
engine. The calculateds keys are placed in the
.Fa auth_key
and
.Fa priv_key
fields of the
.Fa user .
.Pp
The function
.Fn snmp_calc_keychange
calculates a binary key change octet string based on the contents of an old and
a new binary localized key. The rezult is placed in the buffer pointer to by
.Fa keychange
and may be used by an SNMPv3 user who wishes to change his/her password
or localized key.
.Pp
The function
.Fn TRUTH_MK
takes a C truth value (zero or non-zero) and makes an SNMP truth value (2 or 1).
The function
@ -281,6 +446,13 @@ A variable binding value was out of the allowed range.
The PDU is of an unsupported version.
.It Bq Er SNMP_CODE_BADENQ
There was an ASN.1 value with an unsupported tag.
.It Bq Er SNMP_CODE_BADSECLEVEL
The requested securityLevel contained in the PDU is not supported.
.It Bq Er SNMP_CODE_BADDIGEST
The PDU authentication parameter received in the PDU did not match the
calculated message digest.
.It Bq Er SNMP_CODE_EDECRYPT
Error occured while trying to decrypt the PDU.
.El
.Pp
.Fn snmp_pdu_encode
@ -297,8 +469,21 @@ Encoding failed.
.Xr bsnmpagent 3 ,
.Xr bsnmpclient 3 ,
.Xr bsnmplib 3
.Sh CAVEAT
The SNMPv3 message digests, encryption and decryption, and key routines use
the cryptographic functions from
.Xr crypto 3 .
The library may optionally be built without references to the
.Xr crypto 3
library. In such case only plain text SNMPv3 PDUs without message digests
may be proccessed correctly.
.Sh STANDARDS
This implementation conforms to the applicable IETF RFCs and ITU-T
recommendations.
.Sh AUTHORS
The Begemot SNMP library was originally written by
.An Hartmut Brandt Aq harti@FreeBSD.org
.Pp
.An Shteryana Shopova Aq syrinx@FreeBSD.org
added support for the SNMPv3 message proccessing and User-Based
Security model message authentication and privacy.

View File

@ -5,6 +5,12 @@
*
* Author: Harti Brandt <harti@freebsd.org>
*
* Copyright (c) 2010 The FreeBSD Foundation
* All rights reserved.
*
* Portions of this software were developed by Shteryana Sotirova Shopova
* under sponsorship from the FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@ -271,112 +277,144 @@ parse_pdus(struct asn_buf *b, struct snmp_pdu *pdu, int32_t *ip)
return (err);
}
/*
* Parse the outer SEQUENCE value. ASN_ERR_TAG means 'bad version'.
*/
enum asn_err
snmp_parse_message_hdr(struct asn_buf *b, struct snmp_pdu *pdu, asn_len_t *lenp)
static enum asn_err
parse_secparams(struct asn_buf *b, struct snmp_pdu *pdu)
{
int32_t version;
u_char type;
u_int comm_len;
asn_len_t octs_len;
u_char buf[256]; /* XXX: calc max possible size here */
struct asn_buf tb;
if (asn_get_integer(b, &version) != ASN_ERR_OK) {
snmp_error("cannot decode version");
memset(buf, 0, 256);
tb.asn_ptr = buf;
tb.asn_len = 256;
if (asn_get_octetstring(b, buf, &tb.asn_len) != ASN_ERR_OK) {
snmp_error("cannot parse usm header");
return (ASN_ERR_FAILED);
}
if (version == 0) {
pdu->version = SNMP_V1;
} else if (version == 1) {
pdu->version = SNMP_V2c;
} else {
pdu->version = SNMP_Verr;
snmp_error("unsupported SNMP version");
return (ASN_ERR_TAG);
}
comm_len = SNMP_COMMUNITY_MAXLEN;
if (asn_get_octetstring(b, (u_char *)pdu->community,
&comm_len) != ASN_ERR_OK) {
snmp_error("cannot decode community");
return (ASN_ERR_FAILED);
}
pdu->community[comm_len] = '\0';
if (asn_get_header(b, &type, lenp) != ASN_ERR_OK) {
snmp_error("cannot get pdu header");
return (ASN_ERR_FAILED);
}
if ((type & ~ASN_TYPE_MASK) !=
(ASN_TYPE_CONSTRUCTED | ASN_CLASS_CONTEXT)) {
snmp_error("bad pdu header tag");
return (ASN_ERR_FAILED);
}
pdu->type = type & ASN_TYPE_MASK;
switch (pdu->type) {
case SNMP_PDU_GET:
case SNMP_PDU_GETNEXT:
case SNMP_PDU_RESPONSE:
case SNMP_PDU_SET:
break;
case SNMP_PDU_TRAP:
if (pdu->version != SNMP_V1) {
snmp_error("bad pdu type %u", pdu->type);
return (ASN_ERR_FAILED);
}
break;
case SNMP_PDU_GETBULK:
case SNMP_PDU_INFORM:
case SNMP_PDU_TRAP2:
case SNMP_PDU_REPORT:
if (pdu->version == SNMP_V1) {
snmp_error("bad pdu type %u", pdu->type);
return (ASN_ERR_FAILED);
}
break;
default:
snmp_error("bad pdu type %u", pdu->type);
if (asn_get_sequence(&tb, &octs_len) != ASN_ERR_OK) {
snmp_error("cannot decode usm header");
return (ASN_ERR_FAILED);
}
if (*lenp > b->asn_len) {
snmp_error("pdu length too long");
octs_len = SNMP_ENGINE_ID_SIZ;
if (asn_get_octetstring(&tb, (u_char *)&pdu->engine.engine_id,
&octs_len) != ASN_ERR_OK) {
snmp_error("cannot decode msg engine id");
return (ASN_ERR_FAILED);
}
pdu->engine.engine_len = octs_len;
if (asn_get_integer(&tb, &pdu->engine.engine_boots) != ASN_ERR_OK) {
snmp_error("cannot decode msg engine boots");
return (ASN_ERR_FAILED);
}
if (asn_get_integer(&tb, &pdu->engine.engine_time) != ASN_ERR_OK) {
snmp_error("cannot decode msg engine time");
return (ASN_ERR_FAILED);
}
octs_len = SNMP_ADM_STR32_SIZ - 1;
if (asn_get_octetstring(&tb, (u_char *)&pdu->user.sec_name, &octs_len)
!= ASN_ERR_OK) {
snmp_error("cannot decode msg user name");
return (ASN_ERR_FAILED);
}
pdu->user.sec_name[octs_len] = '\0';
octs_len = sizeof(pdu->msg_digest);
if (asn_get_octetstring(&tb, (u_char *)&pdu->msg_digest, &octs_len) !=
ASN_ERR_OK || ((pdu->flags & SNMP_MSG_AUTH_FLAG) != 0 &&
octs_len != sizeof(pdu->msg_digest))) {
snmp_error("cannot decode msg authentication param");
return (ASN_ERR_FAILED);
}
octs_len = sizeof(pdu->msg_salt);
if (asn_get_octetstring(&tb, (u_char *)&pdu->msg_salt, &octs_len) !=
ASN_ERR_OK ||((pdu->flags & SNMP_MSG_PRIV_FLAG) != 0 &&
octs_len != sizeof(pdu->msg_salt))) {
snmp_error("cannot decode msg authentication param");
return (ASN_ERR_FAILED);
}
if ((pdu->flags & SNMP_MSG_AUTH_FLAG) != 0) {
pdu->digest_ptr = b->asn_ptr - SNMP_USM_AUTH_SIZE;
pdu->digest_ptr -= octs_len + ASN_MAXLENLEN;
}
return (ASN_ERR_OK);
}
static enum asn_err
parse_message(struct asn_buf *b, struct snmp_pdu *pdu, int32_t *ip)
static enum snmp_code
pdu_encode_secparams(struct asn_buf *b, struct snmp_pdu *pdu)
{
enum asn_err err;
asn_len_t len, trailer;
u_char buf[256], *sptr;
struct asn_buf tb;
size_t auth_off, moved = 0;
err = snmp_parse_message_hdr(b, pdu, &len);
if (ASN_ERR_STOPPED(err))
return (err);
auth_off = 0;
memset(buf, 0, 256);
tb.asn_ptr = buf;
tb.asn_len = 256;
trailer = b->asn_len - len;
b->asn_len = len;
if (asn_put_temp_header(&tb, (ASN_TYPE_SEQUENCE|ASN_TYPE_CONSTRUCTED),
&sptr) != ASN_ERR_OK)
return (SNMP_CODE_FAILED);
err = parse_pdus(b, pdu, ip);
if (ASN_ERR_STOPPED(err))
return (ASN_ERR_FAILED);
if (asn_put_octetstring(&tb, (u_char *)pdu->engine.engine_id,
pdu->engine.engine_len) != ASN_ERR_OK)
return (SNMP_CODE_FAILED);
if (b->asn_len != 0)
snmp_error("ignoring trailing junk after pdu");
if (asn_put_integer(&tb, pdu->engine.engine_boots) != ASN_ERR_OK)
return (SNMP_CODE_FAILED);
b->asn_len = trailer;
if (asn_put_integer(&tb, pdu->engine.engine_time) != ASN_ERR_OK)
return (SNMP_CODE_FAILED);
return (err);
if (asn_put_octetstring(&tb, (u_char *)pdu->user.sec_name,
strlen(pdu->user.sec_name)) != ASN_ERR_OK)
return (SNMP_CODE_FAILED);
if ((pdu->flags & SNMP_MSG_AUTH_FLAG) != 0) {
auth_off = sizeof(buf) - tb.asn_len + ASN_MAXLENLEN;
if (asn_put_octetstring(&tb, (u_char *)pdu->msg_digest,
sizeof(pdu->msg_digest)) != ASN_ERR_OK)
return (SNMP_CODE_FAILED);
} else {
if (asn_put_octetstring(&tb, (u_char *)pdu->msg_digest, 0)
!= ASN_ERR_OK)
return (SNMP_CODE_FAILED);
}
if ((pdu->flags & SNMP_MSG_PRIV_FLAG) != 0) {
if (asn_put_octetstring(&tb, (u_char *)pdu->msg_salt,
sizeof(pdu->msg_salt)) != ASN_ERR_OK)
return (SNMP_CODE_FAILED);
} else {
if (asn_put_octetstring(&tb, (u_char *)pdu->msg_salt, 0)
!= ASN_ERR_OK)
return (SNMP_CODE_FAILED);
}
if (asn_commit_header(&tb, sptr, &moved) != ASN_ERR_OK)
return (SNMP_CODE_FAILED);
if ((pdu->flags & SNMP_MSG_AUTH_FLAG) != 0)
pdu->digest_ptr = b->asn_ptr + auth_off - moved;
if (asn_put_octetstring(b, buf, sizeof(buf) - tb.asn_len) != ASN_ERR_OK)
return (SNMP_CODE_FAILED);
pdu->digest_ptr += ASN_MAXLENLEN;
if ((pdu->flags & SNMP_MSG_PRIV_FLAG) != 0 && asn_put_temp_header(b,
ASN_TYPE_OCTETSTRING, &pdu->encrypted_ptr) != ASN_ERR_OK)
return (SNMP_CODE_FAILED);
return (SNMP_CODE_OK);
}
/*
@ -388,9 +426,45 @@ parse_message(struct asn_buf *b, struct snmp_pdu *pdu, int32_t *ip)
enum snmp_code
snmp_pdu_decode(struct asn_buf *b, struct snmp_pdu *pdu, int32_t *ip)
{
enum snmp_code code;
if ((code = snmp_pdu_decode_header(b, pdu)) != SNMP_CODE_OK)
return (code);
if (pdu->version == SNMP_V3) {
if (pdu->security_model != SNMP_SECMODEL_USM)
return (SNMP_CODE_FAILED);
if ((code = snmp_pdu_decode_secmode(b, pdu)) != SNMP_CODE_OK)
return (code);
}
code = snmp_pdu_decode_scoped(b, pdu, ip);
switch (code) {
case SNMP_CODE_FAILED:
snmp_pdu_free(pdu);
break;
case SNMP_CODE_BADENC:
if (pdu->version == SNMP_Verr)
return (SNMP_CODE_BADVERS);
default:
break;
}
return (code);
}
enum snmp_code
snmp_pdu_decode_header(struct asn_buf *b, struct snmp_pdu *pdu)
{
int32_t version;
u_int octs_len;
asn_len_t len;
memset(pdu, 0, sizeof(*pdu));
pdu->outer_ptr = b->asn_ptr;
pdu->outer_len = b->asn_len;
if (asn_get_sequence(b, &len) != ASN_ERR_OK) {
snmp_error("cannot decode pdu header");
@ -405,32 +479,192 @@ snmp_pdu_decode(struct asn_buf *b, struct snmp_pdu *pdu, int32_t *ip)
b->asn_len = len;
}
switch (parse_message(b, pdu, ip)) {
case ASN_ERR_OK:
return (SNMP_CODE_OK);
case ASN_ERR_FAILED:
case ASN_ERR_EOBUF:
snmp_pdu_free(pdu);
if (asn_get_integer(b, &version) != ASN_ERR_OK) {
snmp_error("cannot decode version");
return (SNMP_CODE_FAILED);
}
case ASN_ERR_BADLEN:
return (SNMP_CODE_BADLEN);
if (version == 0)
pdu->version = SNMP_V1;
else if (version == 1)
pdu->version = SNMP_V2c;
else if (version == 3)
pdu->version = SNMP_V3;
else {
pdu->version = SNMP_Verr;
snmp_error("unsupported SNMP version");
return (SNMP_CODE_BADENC);
}
case ASN_ERR_RANGE:
return (SNMP_CODE_OORANGE);
if (pdu->version == SNMP_V3) {
if (asn_get_sequence(b, &len) != ASN_ERR_OK) {
snmp_error("cannot decode pdu global data header");
return (SNMP_CODE_FAILED);
}
case ASN_ERR_TAG:
if (pdu->version == SNMP_Verr)
return (SNMP_CODE_BADVERS);
else
return (SNMP_CODE_BADENC);
if (asn_get_integer(b, &pdu->identifier) != ASN_ERR_OK) {
snmp_error("cannot decode msg indetifier");
return (SNMP_CODE_FAILED);
}
if (asn_get_integer(b, &pdu->engine.max_msg_size)
!= ASN_ERR_OK) {
snmp_error("cannot decode msg size");
return (SNMP_CODE_FAILED);
}
octs_len = 1;
if (asn_get_octetstring(b, (u_char *)&pdu->flags,
&octs_len) != ASN_ERR_OK) {
snmp_error("cannot decode msg flags");
return (SNMP_CODE_FAILED);
}
if (asn_get_integer(b, &pdu->security_model) != ASN_ERR_OK) {
snmp_error("cannot decode msg size");
return (SNMP_CODE_FAILED);
}
if (pdu->security_model != SNMP_SECMODEL_USM)
return (SNMP_CODE_FAILED);
if (parse_secparams(b, pdu) != ASN_ERR_OK)
return (SNMP_CODE_FAILED);
} else {
octs_len = SNMP_COMMUNITY_MAXLEN;
if (asn_get_octetstring(b, (u_char *)pdu->community,
&octs_len) != ASN_ERR_OK) {
snmp_error("cannot decode community");
return (SNMP_CODE_FAILED);
}
pdu->community[octs_len] = '\0';
}
return (SNMP_CODE_OK);
}
enum snmp_code
snmp_pdu_decode_scoped(struct asn_buf *b, struct snmp_pdu *pdu, int32_t *ip)
{
u_char type;
asn_len_t len, trailer;
enum asn_err err;
if (pdu->version == SNMP_V3) {
if (asn_get_sequence(b, &len) != ASN_ERR_OK) {
snmp_error("cannot decode scoped pdu header");
return (SNMP_CODE_FAILED);
}
len = SNMP_ENGINE_ID_SIZ;
if (asn_get_octetstring(b, (u_char *)&pdu->context_engine,
&len) != ASN_ERR_OK) {
snmp_error("cannot decode msg context engine");
return (SNMP_CODE_FAILED);
}
pdu->context_engine_len = len;
len = SNMP_CONTEXT_NAME_SIZ;
if (asn_get_octetstring(b, (u_char *)&pdu->context_name,
&len) != ASN_ERR_OK) {
snmp_error("cannot decode msg context name");
return (SNMP_CODE_FAILED);
}
pdu->context_name[len] = '\0';
}
if (asn_get_header(b, &type, &len) != ASN_ERR_OK) {
snmp_error("cannot get pdu header");
return (SNMP_CODE_FAILED);
}
if ((type & ~ASN_TYPE_MASK) !=
(ASN_TYPE_CONSTRUCTED | ASN_CLASS_CONTEXT)) {
snmp_error("bad pdu header tag");
return (SNMP_CODE_FAILED);
}
pdu->type = type & ASN_TYPE_MASK;
switch (pdu->type) {
case SNMP_PDU_GET:
case SNMP_PDU_GETNEXT:
case SNMP_PDU_RESPONSE:
case SNMP_PDU_SET:
break;
case SNMP_PDU_TRAP:
if (pdu->version != SNMP_V1) {
snmp_error("bad pdu type %u", pdu->type);
return (SNMP_CODE_FAILED);
}
break;
case SNMP_PDU_GETBULK:
case SNMP_PDU_INFORM:
case SNMP_PDU_TRAP2:
case SNMP_PDU_REPORT:
if (pdu->version == SNMP_V1) {
snmp_error("bad pdu type %u", pdu->type);
return (SNMP_CODE_FAILED);
}
break;
default:
snmp_error("bad pdu type %u", pdu->type);
return (SNMP_CODE_FAILED);
}
trailer = b->asn_len - len;
b->asn_len = len;
err = parse_pdus(b, pdu, ip);
if (ASN_ERR_STOPPED(err))
return (SNMP_CODE_FAILED);
if (b->asn_len != 0)
snmp_error("ignoring trailing junk after pdu");
b->asn_len = trailer;
return (SNMP_CODE_OK);
}
enum snmp_code
snmp_pdu_decode_secmode(struct asn_buf *b, struct snmp_pdu *pdu)
{
u_char type;
enum snmp_code code;
uint8_t digest[SNMP_USM_AUTH_SIZE];
if (pdu->user.auth_proto != SNMP_AUTH_NOAUTH &&
(pdu->flags & SNMP_MSG_AUTH_FLAG) == 0)
return (SNMP_CODE_BADSECLEVEL);
if ((code = snmp_pdu_calc_digest(b, pdu, digest)) !=
SNMP_CODE_OK)
return (SNMP_CODE_FAILED);
if (pdu->user.auth_proto != SNMP_AUTH_NOAUTH &&
memcmp(digest, pdu->msg_digest, sizeof(pdu->msg_digest)) != 0)
return (SNMP_CODE_BADDIGEST);
if (pdu->user.priv_proto != SNMP_PRIV_NOPRIV && (asn_get_header(b, &type,
&pdu->scoped_len) != ASN_ERR_OK || type != ASN_TYPE_OCTETSTRING)) {
snmp_error("cannot decode encrypted pdu");
return (SNMP_CODE_FAILED);
}
pdu->scoped_ptr = b->asn_ptr;
if (pdu->user.priv_proto != SNMP_PRIV_NOPRIV &&
(pdu->flags & SNMP_MSG_PRIV_FLAG) == 0)
return (SNMP_CODE_BADSECLEVEL);
if ((code = snmp_pdu_decrypt(b, pdu)) != SNMP_CODE_OK)
return (SNMP_CODE_FAILED);
return (code);
}
/*
* Check whether what we have is the complete PDU by snooping at the
* enclosing structure header. This returns:
@ -500,6 +734,7 @@ enum snmp_code
snmp_pdu_encode_header(struct asn_buf *b, struct snmp_pdu *pdu)
{
enum asn_err err;
u_char *v3_hdr_ptr;
if (asn_put_temp_header(b, (ASN_TYPE_SEQUENCE|ASN_TYPE_CONSTRUCTED),
&pdu->outer_ptr) != ASN_ERR_OK)
@ -509,14 +744,62 @@ snmp_pdu_encode_header(struct asn_buf *b, struct snmp_pdu *pdu)
err = asn_put_integer(b, 0);
else if (pdu->version == SNMP_V2c)
err = asn_put_integer(b, 1);
else if (pdu->version == SNMP_V3)
err = asn_put_integer(b, 3);
else
return (SNMP_CODE_BADVERS);
if (err != ASN_ERR_OK)
return (SNMP_CODE_FAILED);
if (asn_put_octetstring(b, (u_char *)pdu->community,
strlen(pdu->community)) != ASN_ERR_OK)
return (SNMP_CODE_FAILED);
if (pdu->version == SNMP_V3) {
if (asn_put_temp_header(b, (ASN_TYPE_SEQUENCE |
ASN_TYPE_CONSTRUCTED), &v3_hdr_ptr) != ASN_ERR_OK)
return (SNMP_CODE_FAILED);
if (asn_put_integer(b, pdu->identifier) != ASN_ERR_OK)
return (SNMP_CODE_FAILED);
if (asn_put_integer(b, pdu->engine.max_msg_size) != ASN_ERR_OK)
return (SNMP_CODE_FAILED);
if (pdu->type != SNMP_PDU_RESPONSE &&
pdu->type != SNMP_PDU_TRAP &&
pdu->type != SNMP_PDU_REPORT)
pdu->flags |= SNMP_MSG_REPORT_FLAG;
if (asn_put_octetstring(b, (u_char *)&pdu->flags, 1)
!= ASN_ERR_OK)
return (SNMP_CODE_FAILED);
if (asn_put_integer(b, pdu->security_model) != ASN_ERR_OK)
return (SNMP_CODE_FAILED);
if (asn_commit_header(b, v3_hdr_ptr, NULL) != ASN_ERR_OK)
return (SNMP_CODE_FAILED);
if (pdu->security_model != SNMP_SECMODEL_USM)
return (SNMP_CODE_FAILED);
if (pdu_encode_secparams(b, pdu) != SNMP_CODE_OK)
return (SNMP_CODE_FAILED);
/* View-based Access Conntrol information */
if (asn_put_temp_header(b, (ASN_TYPE_SEQUENCE |
ASN_TYPE_CONSTRUCTED), &pdu->scoped_ptr) != ASN_ERR_OK)
return (SNMP_CODE_FAILED);
if (asn_put_octetstring(b, (u_char *)pdu->context_engine,
pdu->context_engine_len) != ASN_ERR_OK)
return (SNMP_CODE_FAILED);
if (asn_put_octetstring(b, (u_char *)pdu->context_name,
strlen(pdu->context_name)) != ASN_ERR_OK)
return (SNMP_CODE_FAILED);
} else {
if (asn_put_octetstring(b, (u_char *)pdu->community,
strlen(pdu->community)) != ASN_ERR_OK)
return (SNMP_CODE_FAILED);
}
if (asn_put_temp_header(b, (ASN_TYPE_CONSTRUCTED | ASN_CLASS_CONTEXT |
pdu->type), &pdu->pdu_ptr) != ASN_ERR_OK)
@ -550,13 +833,66 @@ snmp_pdu_encode_header(struct asn_buf *b, struct snmp_pdu *pdu)
return (SNMP_CODE_OK);
}
enum snmp_code
snmp_fix_encoding(struct asn_buf *b, const struct snmp_pdu *pdu)
static enum asn_err
snmp_pdu_fix_padd(struct asn_buf *b, struct snmp_pdu *pdu)
{
if (asn_commit_header(b, pdu->vars_ptr) != ASN_ERR_OK ||
asn_commit_header(b, pdu->pdu_ptr) != ASN_ERR_OK ||
asn_commit_header(b, pdu->outer_ptr) != ASN_ERR_OK)
asn_len_t padlen;
if (pdu->user.priv_proto == SNMP_PRIV_DES && pdu->scoped_len % 8 != 0) {
padlen = 8 - (pdu->scoped_len % 8);
if (asn_pad(b, padlen) != ASN_ERR_OK)
return (ASN_ERR_FAILED);
pdu->scoped_len += padlen;
}
return (ASN_ERR_OK);
}
enum snmp_code
snmp_fix_encoding(struct asn_buf *b, struct snmp_pdu *pdu)
{
size_t moved = 0;
enum snmp_code code;
if (asn_commit_header(b, pdu->vars_ptr, NULL) != ASN_ERR_OK ||
asn_commit_header(b, pdu->pdu_ptr, NULL) != ASN_ERR_OK)
return (SNMP_CODE_FAILED);
if (pdu->version == SNMP_V3) {
if (asn_commit_header(b, pdu->scoped_ptr, NULL) != ASN_ERR_OK)
return (SNMP_CODE_FAILED);
pdu->scoped_len = b->asn_ptr - pdu->scoped_ptr;
if ((code = snmp_pdu_fix_padd(b, pdu))!= ASN_ERR_OK)
return (SNMP_CODE_FAILED);
if (pdu->security_model != SNMP_SECMODEL_USM)
return (SNMP_CODE_FAILED);
if (snmp_pdu_encrypt(b, pdu) != SNMP_CODE_OK)
return (SNMP_CODE_FAILED);
if (pdu->user.priv_proto != SNMP_PRIV_NOPRIV &&
asn_commit_header(b, pdu->encrypted_ptr, NULL) != ASN_ERR_OK)
return (SNMP_CODE_FAILED);
}
if (asn_commit_header(b, pdu->outer_ptr, &moved) != ASN_ERR_OK)
return (SNMP_CODE_FAILED);
pdu->outer_len = b->asn_ptr - pdu->outer_ptr;
pdu->digest_ptr -= moved;
if (pdu->version == SNMP_V3) {
if ((code = snmp_pdu_calc_digest(b, pdu, pdu->msg_digest)) !=
SNMP_CODE_OK)
return (SNMP_CODE_FAILED);
if ((pdu->flags & SNMP_MSG_AUTH_FLAG) != 0)
memcpy(pdu->digest_ptr, pdu->msg_digest,
sizeof(pdu->msg_digest));
}
return (SNMP_CODE_OK);
}
@ -639,7 +975,7 @@ snmp_binding_encode(struct asn_buf *b, const struct snmp_value *binding)
return (err);
}
err = asn_commit_header(b, ptr);
err = asn_commit_header(b, ptr, NULL);
if (err != ASN_ERR_OK) {
*b = save;
return (err);
@ -775,6 +1111,8 @@ snmp_pdu_dump(const struct snmp_pdu *pdu)
vers = "SNMPv1";
else if (pdu->version == SNMP_V2c)
vers = "SNMPv2c";
else if (pdu->version == SNMP_V3)
vers = "SNMPv3";
else
vers = "v?";
@ -837,6 +1175,39 @@ snmp_value_copy(struct snmp_value *to, const struct snmp_value *from)
return (0);
}
void
snmp_pdu_init_secparams(struct snmp_pdu *pdu, struct snmp_engine *eng,
struct snmp_user *user)
{
int32_t rval;
memcpy(&pdu->engine, eng, sizeof(pdu->engine));
memcpy(&pdu->user, user, sizeof(pdu->user));
if (user->auth_proto != SNMP_AUTH_NOAUTH)
pdu->flags |= SNMP_MSG_AUTH_FLAG;
switch (user->priv_proto) {
case SNMP_PRIV_DES:
memcpy(pdu->msg_salt, &eng->engine_boots,
sizeof(eng->engine_boots));
rval = random();
memcpy(pdu->msg_salt + sizeof(eng->engine_boots), &rval,
sizeof(int32_t));
pdu->flags |= SNMP_MSG_PRIV_FLAG;
break;
case SNMP_PRIV_AES:
rval = random();
memcpy(pdu->msg_salt, &rval, sizeof(int32_t));
rval = random();
memcpy(pdu->msg_salt + sizeof(int32_t), &rval, sizeof(int32_t));
pdu->flags |= SNMP_MSG_PRIV_FLAG;
break;
default:
break;
}
}
void
snmp_pdu_free(struct snmp_pdu *pdu)
{

View File

@ -5,6 +5,13 @@
*
* Author: Harti Brandt <harti@freebsd.org>
*
* Copyright (c) 2010 The FreeBSD Foundation
* All rights reserved.
*
* Portions of this software were developed by Shteryana Sotirova Shopova
* under sponsorship from the FreeBSD Foundation.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@ -35,8 +42,11 @@
#include <sys/types.h>
#define SNMP_COMMUNITY_MAXLEN 128
#define SNMP_MAX_BINDINGS 100
#define SNMP_COMMUNITY_MAXLEN 128
#define SNMP_MAX_BINDINGS 100
#define SNMP_CONTEXT_NAME_SIZ (32 + 1)
#define SNMP_ENGINE_ID_SIZ 32
#define SNMP_TIME_WINDOW 150
enum snmp_syntax {
SNMP_SYNTAX_NULL = 0,
@ -75,33 +85,110 @@ struct snmp_value {
enum snmp_version {
SNMP_Verr = 0,
SNMP_V1 = 1,
SNMP_V2c,
SNMP_V2c = 2,
SNMP_V3,
};
#define SNMP_ADM_STR32_SIZ (32 + 1)
#define SNMP_AUTH_KEY_SIZ 40
#define SNMP_PRIV_KEY_SIZ 32
#define SNMP_USM_AUTH_SIZE 12
#define SNMP_USM_PRIV_SIZE 8
#define SNMP_AUTH_HMACMD5_KEY_SIZ 16
#define SNMP_AUTH_HMACSHA_KEY_SIZ 20
#define SNMP_PRIV_AES_KEY_SIZ 16
#define SNMP_PRIV_DES_KEY_SIZ 8
enum snmp_secmodel {
SNMP_SECMODEL_ANY = 0,
SNMP_SECMODEL_SNMPv1 = 1,
SNMP_SECMODEL_SNMPv2c = 2,
SNMP_SECMODEL_USM = 3,
SNMP_SECMODEL_UNKNOWN
};
enum snmp_usm_level {
SNMP_noAuthNoPriv = 1,
SNMP_authNoPriv = 2,
SNMP_authPriv = 3
};
enum snmp_authentication {
SNMP_AUTH_NOAUTH = 0,
SNMP_AUTH_HMAC_MD5,
SNMP_AUTH_HMAC_SHA
};
enum snmp_privacy {
SNMP_PRIV_NOPRIV = 0,
SNMP_PRIV_DES = 1,
SNMP_PRIV_AES
};
struct snmp_engine {
uint8_t engine_id[SNMP_ENGINE_ID_SIZ];
uint32_t engine_len;
int32_t engine_boots;
int32_t engine_time;
int32_t max_msg_size;
};
struct snmp_user {
char sec_name[SNMP_ADM_STR32_SIZ];
enum snmp_authentication auth_proto;
enum snmp_privacy priv_proto;
uint8_t auth_key[SNMP_AUTH_KEY_SIZ];
uint8_t priv_key[SNMP_PRIV_KEY_SIZ];
};
struct snmp_pdu {
char community[SNMP_COMMUNITY_MAXLEN + 1];
enum snmp_version version;
u_int type;
char community[SNMP_COMMUNITY_MAXLEN + 1];
enum snmp_version version;
u_int type;
/* SNMPv3 PDU header fields */
int32_t identifier;
uint8_t flags;
int32_t security_model;
struct snmp_engine engine;
/* Associated USM user parameters */
struct snmp_user user;
uint8_t msg_digest[SNMP_USM_AUTH_SIZE];
uint8_t msg_salt[SNMP_USM_PRIV_SIZE];
/* View-based Access Model */
/* XXX: put in separate structure - conflicts with struct snmp_context */
uint32_t context_engine_len;
uint8_t context_engine[SNMP_ENGINE_ID_SIZ];
char context_name[SNMP_CONTEXT_NAME_SIZ];
/* trap only */
struct asn_oid enterprise;
u_char agent_addr[4];
int32_t generic_trap;
int32_t specific_trap;
uint32_t time_stamp;
struct asn_oid enterprise;
u_char agent_addr[4];
int32_t generic_trap;
int32_t specific_trap;
uint32_t time_stamp;
/* others */
int32_t request_id;
int32_t error_status;
int32_t error_index;
int32_t request_id;
int32_t error_status;
int32_t error_index;
/* fixes for encoding */
u_char *outer_ptr;
u_char *pdu_ptr;
u_char *vars_ptr;
size_t outer_len;
size_t scoped_len;
u_char *outer_ptr;
u_char *digest_ptr;
u_char *encrypted_ptr;
u_char *scoped_ptr;
u_char *pdu_ptr;
u_char *vars_ptr;
struct snmp_value bindings[SNMP_MAX_BINDINGS];
u_int nbindings;
struct snmp_value bindings[SNMP_MAX_BINDINGS];
u_int nbindings;
};
#define snmp_v1_pdu snmp_pdu
@ -150,20 +237,38 @@ enum snmp_code {
SNMP_CODE_BADLEN,
SNMP_CODE_BADENC,
SNMP_CODE_OORANGE,
SNMP_CODE_BADSECLEVEL,
SNMP_CODE_NOTINTIME,
SNMP_CODE_BADUSER,
SNMP_CODE_BADENGINE,
SNMP_CODE_BADDIGEST,
SNMP_CODE_EDECRYPT
};
#define SNMP_MSG_AUTH_FLAG 0x1
#define SNMP_MSG_PRIV_FLAG 0x2
#define SNMP_MSG_REPORT_FLAG 0x4
#define SNMP_MSG_AUTODISCOVER 0x80
void snmp_value_free(struct snmp_value *);
int snmp_value_parse(const char *, enum snmp_syntax, union snmp_values *);
int snmp_value_copy(struct snmp_value *, const struct snmp_value *);
void snmp_pdu_free(struct snmp_pdu *);
enum snmp_code snmp_pdu_decode(struct asn_buf *b, struct snmp_pdu *pdu, int32_t *);
enum snmp_code snmp_pdu_encode(struct snmp_pdu *pdu, struct asn_buf *resp_b);
enum snmp_code snmp_pdu_decode_header(struct asn_buf *, struct snmp_pdu *);
enum snmp_code snmp_pdu_decode_scoped(struct asn_buf *, struct snmp_pdu *, int32_t *);
enum snmp_code snmp_pdu_encode(struct snmp_pdu *, struct asn_buf *);
enum snmp_code snmp_pdu_decode_secmode(struct asn_buf *, struct snmp_pdu *);
int snmp_pdu_snoop(const struct asn_buf *);
void snmp_pdu_dump(const struct snmp_pdu *pdu);
enum snmp_code snmp_passwd_to_keys(struct snmp_user *, char *);
enum snmp_code snmp_get_local_keys(struct snmp_user *, uint8_t *, uint32_t);
enum snmp_code snmp_calc_keychange(struct snmp_user *, uint8_t *);
extern void (*snmp_error)(const char *, ...);
extern void (*snmp_printf)(const char *, ...);

View File

@ -165,6 +165,29 @@ find_subnode(const struct snmp_value *value)
return (NULL);
}
static void
snmp_pdu_create_response(struct snmp_pdu *pdu, struct snmp_pdu *resp)
{
memset(resp, 0, sizeof(*resp));
strcpy(resp->community, pdu->community);
resp->version = pdu->version;
resp->type = SNMP_PDU_RESPONSE;
resp->request_id = pdu->request_id;
resp->version = pdu->version;
if (resp->version != SNMP_V3)
return;
snmp_pdu_init_secparams(resp, &pdu->engine, &pdu->user);
resp->identifier = pdu->identifier;
resp->security_model = pdu->security_model;
resp->context_engine_len = pdu->context_engine_len;
memcpy(resp->context_engine, pdu->context_engine,
resp->context_engine_len);
strlcpy(resp->context_name, pdu->context_name,
sizeof(resp->context_name));
}
/*
* Execute a GET operation. The tree is rooted at the global 'root'.
* Build the response PDU on the fly. If the return code is SNMP_RET_ERR
@ -184,12 +207,7 @@ snmp_get(struct snmp_pdu *pdu, struct asn_buf *resp_b,
memset(&context, 0, sizeof(context));
context.ctx.data = data;
memset(resp, 0, sizeof(*resp));
strcpy(resp->community, pdu->community);
resp->version = pdu->version;
resp->type = SNMP_PDU_RESPONSE;
resp->request_id = pdu->request_id;
resp->version = pdu->version;
snmp_pdu_create_response(pdu, resp);
if (snmp_pdu_encode_header(resp_b, resp) != SNMP_CODE_OK)
/* cannot even encode header - very bad */
@ -384,11 +402,7 @@ snmp_getnext(struct snmp_pdu *pdu, struct asn_buf *resp_b,
memset(&context, 0, sizeof(context));
context.ctx.data = data;
memset(resp, 0, sizeof(*resp));
strcpy(resp->community, pdu->community);
resp->type = SNMP_PDU_RESPONSE;
resp->request_id = pdu->request_id;
resp->version = pdu->version;
snmp_pdu_create_response(pdu, resp);
if (snmp_pdu_encode_header(resp_b, resp))
return (SNMP_RET_IGN);
@ -440,12 +454,7 @@ snmp_getbulk(struct snmp_pdu *pdu, struct asn_buf *resp_b,
memset(&context, 0, sizeof(context));
context.ctx.data = data;
memset(resp, 0, sizeof(*resp));
strcpy(resp->community, pdu->community);
resp->version = pdu->version;
resp->type = SNMP_PDU_RESPONSE;
resp->request_id = pdu->request_id;
resp->version = pdu->version;
snmp_pdu_create_response(pdu, resp);
if (snmp_pdu_encode_header(resp_b, resp) != SNMP_CODE_OK)
/* cannot even encode header - very bad */
@ -652,11 +661,7 @@ snmp_set(struct snmp_pdu *pdu, struct asn_buf *resp_b,
TAILQ_INIT(&context.dlist);
context.ctx.data = data;
memset(resp, 0, sizeof(*resp));
strcpy(resp->community, pdu->community);
resp->type = SNMP_PDU_RESPONSE;
resp->request_id = pdu->request_id;
resp->version = pdu->version;
snmp_pdu_create_response(pdu, resp);
if (snmp_pdu_encode_header(resp_b, resp))
return (SNMP_RET_IGN);
@ -951,16 +956,9 @@ snmp_make_errresp(const struct snmp_pdu *pdu, struct asn_buf *pdu_b,
enum snmp_code code;
memset(&resp, 0, sizeof(resp));
/* Message sequence */
if (asn_get_sequence(pdu_b, &len) != ASN_ERR_OK)
return (SNMP_RET_IGN);
if (pdu_b->asn_len < len)
if ((code = snmp_pdu_decode_header(pdu_b, &resp)) != SNMP_CODE_OK)
return (SNMP_RET_IGN);
err = snmp_parse_message_hdr(pdu_b, &resp, &len);
if (ASN_ERR_STOPPED(err))
return (SNMP_RET_IGN);
if (pdu_b->asn_len < len)
return (SNMP_RET_IGN);
pdu_b->asn_len = len;

View File

@ -852,6 +852,9 @@ snmp_client_init(struct snmp_client *c)
strcpy(c->read_community, "public");
strcpy(c->write_community, "private");
c->security_model = SNMP_SECMODEL_USM;
strcpy(c->cname, "");
c->timeout.tv_sec = 3;
c->timeout.tv_usec = 0;
@ -864,6 +867,8 @@ snmp_client_init(struct snmp_client *c)
c->max_reqid = INT32_MAX;
c->min_reqid = 0;
c->next_reqid = 0;
c->engine.max_msg_size = 1500; /* XXX */
}
@ -1132,7 +1137,8 @@ snmp_close(void)
void
snmp_pdu_create(struct snmp_pdu *pdu, u_int op)
{
memset(pdu,0,sizeof(struct snmp_pdu));
memset(pdu, 0, sizeof(struct snmp_pdu));
if (op == SNMP_PDU_SET)
strlcpy(pdu->community, snmp_client.write_community,
sizeof(pdu->community));
@ -1145,6 +1151,33 @@ snmp_pdu_create(struct snmp_pdu *pdu, u_int op)
pdu->error_status = 0;
pdu->error_index = 0;
pdu->nbindings = 0;
if (snmp_client.version != SNMP_V3)
return;
pdu->identifier = ++snmp_client.identifier;
pdu->engine.max_msg_size = snmp_client.engine.max_msg_size;
pdu->flags = 0;
pdu->security_model = snmp_client.security_model;
if (snmp_client.security_model == SNMP_SECMODEL_USM)
snmp_pdu_init_secparams(pdu, &snmp_client.engine,
&snmp_client.user);
else
seterr(&snmp_client, "unknown security model");
if (snmp_client.clen > 0) {
memcpy(pdu->context_engine, snmp_client.cengine,
snmp_client.clen);
pdu->context_engine_len = snmp_client.clen;
} else {
memcpy(pdu->context_engine, snmp_client.engine.engine_id,
snmp_client.engine.engine_len);
pdu->context_engine_len = snmp_client.engine.engine_len;
}
strlcpy(pdu->context_name, snmp_client.cname,
sizeof(pdu->context_name));
}
/* add pairs of (struct asn_oid, enum snmp_syntax) to an existing pdu */
@ -1406,15 +1439,24 @@ snmp_receive_packet(struct snmp_pdu *pdu, struct timeval *tv)
abuf.asn_ptr = buf;
abuf.asn_len = ret;
memset(pdu, 0, sizeof(*pdu));
if (snmp_client.security_model == SNMP_SECMODEL_USM)
snmp_pdu_init_secparams(pdu, &snmp_client.engine,
&snmp_client.user);
if (SNMP_CODE_OK != (ret = snmp_pdu_decode(&abuf, pdu, &ip))) {
seterr(&snmp_client, "snmp_decode_pdu: failed %d", ret);
free(buf);
return (-1);
}
free(buf);
if (snmp_client.dump_pdus)
snmp_pdu_dump(pdu);
snmp_client.engine.engine_time = pdu->engine.engine_time;
snmp_client.engine.engine_boots = pdu->engine.engine_boots;
return (+1);
}
@ -1684,6 +1726,93 @@ snmp_dialog(struct snmp_v1_pdu *req, struct snmp_v1_pdu *resp)
return (-1);
}
int
snmp_discover_engine(char *passwd)
{
char cname[SNMP_ADM_STR32_SIZ];
enum snmp_authentication cap;
enum snmp_privacy cpp;
struct snmp_pdu req, resp;
if (snmp_client.version != SNMP_V3)
seterr(&snmp_client, "wrong version");
strlcpy(cname, snmp_client.user.sec_name, sizeof(cname));
cap = snmp_client.user.auth_proto;
cpp = snmp_client.user.priv_proto;
snmp_client.engine.engine_len = 0;
snmp_client.engine.engine_boots = 0;
snmp_client.engine.engine_time = 0;
snmp_client.user.auth_proto = SNMP_AUTH_NOAUTH;
snmp_client.user.priv_proto = SNMP_PRIV_NOPRIV;
memset(snmp_client.user.sec_name, 0, sizeof(snmp_client.user.sec_name));
snmp_pdu_create(&req, SNMP_PDU_GET);
if (snmp_dialog(&req, &resp) == -1)
return (-1);
if (resp.version != req.version) {
seterr(&snmp_client, "wrong version");
return (-1);
}
if (resp.error_status != SNMP_ERR_NOERROR) {
seterr(&snmp_client, "Error %d in responce", resp.error_status);
return (-1);
}
snmp_client.engine.engine_len = resp.engine.engine_len;
snmp_client.engine.max_msg_size = resp.engine.max_msg_size;
memcpy(snmp_client.engine.engine_id, resp.engine.engine_id,
resp.engine.engine_len);
strlcpy(snmp_client.user.sec_name, cname,
sizeof(snmp_client.user.sec_name));
snmp_client.user.auth_proto = cap;
snmp_client.user.priv_proto = cpp;
if (snmp_client.user.auth_proto == SNMP_AUTH_NOAUTH)
return (0);
if (passwd == NULL ||
snmp_passwd_to_keys(&snmp_client.user, passwd) != SNMP_CODE_OK ||
snmp_get_local_keys(&snmp_client.user, snmp_client.engine.engine_id,
snmp_client.engine.engine_len) != SNMP_CODE_OK)
return (-1);
if (resp.engine.engine_boots != 0)
snmp_client.engine.engine_boots = resp.engine.engine_boots;
if (resp.engine.engine_time != 0) {
snmp_client.engine.engine_time = resp.engine.engine_time;
return (0);
}
snmp_pdu_create(&req, SNMP_PDU_GET);
req.engine.engine_boots = 0;
req.engine.engine_time = 0;
if (snmp_dialog(&req, &resp) == -1)
return (-1);
if (resp.version != req.version) {
seterr(&snmp_client, "wrong version");
return (-1);
}
if (resp.error_status != SNMP_ERR_NOERROR) {
seterr(&snmp_client, "Error %d in responce", resp.error_status);
return (-1);
}
snmp_client.engine.engine_boots = resp.engine.engine_boots;
snmp_client.engine.engine_time = resp.engine.engine_time;
return (0);
}
int
snmp_client_set_host(struct snmp_client *cl, const char *h)
{

View File

@ -69,36 +69,47 @@ typedef void (*snmp_timeout_stop_f)(void *timeout_id);
* Client context.
*/
struct snmp_client {
enum snmp_version version;
int trans; /* which transport to use */
enum snmp_version version;
int trans; /* which transport to use */
/* these two are read-only for the application */
char *cport; /* port number as string */
char *chost; /* host name or IP address as string */
char *cport; /* port number as string */
char *chost; /* host name or IP address as string */
char read_community[SNMP_COMMUNITY_MAXLEN + 1];
char write_community[SNMP_COMMUNITY_MAXLEN + 1];
char read_community[SNMP_COMMUNITY_MAXLEN + 1];
char write_community[SNMP_COMMUNITY_MAXLEN + 1];
struct timeval timeout;
u_int retries;
/* SNMPv3 specific fields */
int32_t identifier;
int32_t security_model;
struct snmp_engine engine;
struct snmp_user user;
int dump_pdus;
/* SNMPv3 Access control - VACM*/
uint32_t clen;
uint8_t cengine[SNMP_ENGINE_ID_SIZ];
char cname[SNMP_CONTEXT_NAME_SIZ];
size_t txbuflen;
size_t rxbuflen;
struct timeval timeout;
u_int retries;
int fd;
int dump_pdus;
int32_t next_reqid;
int32_t max_reqid;
int32_t min_reqid;
size_t txbuflen;
size_t rxbuflen;
char error[SNMP_STRERROR_LEN];
int fd;
snmp_timeout_start_f timeout_start;
snmp_timeout_stop_f timeout_stop;
int32_t next_reqid;
int32_t max_reqid;
int32_t min_reqid;
char local_path[sizeof(SNMP_LOCAL_PATH)];
char error[SNMP_STRERROR_LEN];
snmp_timeout_start_f timeout_start;
snmp_timeout_stop_f timeout_stop;
char local_path[sizeof(SNMP_LOCAL_PATH)];
};
/* the global context */
@ -181,6 +192,9 @@ int snmp_table_fetch_async(const struct snmp_table *, void *,
/* send a request and wait for the response */
int snmp_dialog(struct snmp_pdu *_req, struct snmp_pdu *_resp);
/* discover an authorative snmpEngineId */
int snmp_discover_engine(char *);
/* parse a server specification */
int snmp_parse_server(struct snmp_client *, const char *);

View File

@ -0,0 +1,404 @@
/*-
* Copyright (c) 2010 The FreeBSD Foundation
* All rights reserved.
*
* This software was developed by Shteryana Sotirova Shopova under
* sponsorship from the FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdarg.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#elif defined(HAVE_INTTYPES_H)
#include <inttypes.h>
#endif
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <netinet/in.h>
#ifdef HAVE_LIBCRYPTO
#include <openssl/evp.h>
#endif
#include "asn1.h"
#include "snmp.h"
#include "snmppriv.h"
#define SNMP_PRIV_AES_IV_SIZ 16
#define SNMP_EXTENDED_KEY_SIZ 64
#define SNMP_AUTH_KEY_LOOPCNT 1048576
#define SNMP_AUTH_BUF_SIZE 72
static const uint8_t ipad = 0x36;
static const uint8_t opad = 0x5c;
#ifdef HAVE_LIBCRYPTO
static int32_t
snmp_digest_init(const struct snmp_user *user, EVP_MD_CTX *ctx,
const EVP_MD **dtype, uint32_t *keylen)
{
if (user->auth_proto == SNMP_AUTH_HMAC_MD5) {
*dtype = EVP_md5();
*keylen = SNMP_AUTH_HMACMD5_KEY_SIZ;
} else if (user->auth_proto == SNMP_AUTH_HMAC_SHA) {
*dtype = EVP_sha1();
*keylen = SNMP_AUTH_HMACSHA_KEY_SIZ;
} else if (user->auth_proto == SNMP_AUTH_NOAUTH)
return (0);
else {
snmp_error("unknown authentication option - %d",
user->auth_proto);
return (-1);
}
if (EVP_DigestInit(ctx, *dtype) != 1)
return (-1);
return (1);
}
enum snmp_code
snmp_pdu_calc_digest(struct asn_buf *b, const struct snmp_pdu *pdu,
uint8_t *digest)
{
uint8_t md[EVP_MAX_MD_SIZE], extkey[SNMP_EXTENDED_KEY_SIZ];
uint8_t key1[SNMP_EXTENDED_KEY_SIZ], key2[SNMP_EXTENDED_KEY_SIZ];
uint32_t i, keylen, olen;
int32_t err;
const EVP_MD *dtype;
EVP_MD_CTX ctx;
err = snmp_digest_init(&pdu->user, &ctx, &dtype, &keylen);
if (err < 0)
return (SNMP_CODE_BADDIGEST);
else if (err == 0)
return (SNMP_CODE_OK);
memset(pdu->digest_ptr, 0, sizeof(pdu->msg_digest));
memcpy(extkey, pdu->user.auth_key, keylen);
memset(extkey + keylen, 0, sizeof(extkey) - keylen);
for (i = 0; i < SNMP_EXTENDED_KEY_SIZ; i++) {
key1[i] = extkey[i] ^ ipad;
key2[i] = extkey[i] ^ opad;
}
if (EVP_DigestUpdate(&ctx, key1, SNMP_EXTENDED_KEY_SIZ) != 1 ||
EVP_DigestUpdate(&ctx, pdu->outer_ptr, pdu->outer_len) != 1 ||
EVP_DigestFinal(&ctx, md, &olen) != 1)
goto failed;
if (EVP_DigestInit(&ctx, dtype) != 1 ||
EVP_DigestUpdate(&ctx, key2, SNMP_EXTENDED_KEY_SIZ) != 1 ||
EVP_DigestUpdate(&ctx, md, olen) != 1 ||
EVP_DigestFinal(&ctx, md, &olen) != 1)
goto failed;
if (olen < SNMP_USM_AUTH_SIZE) {
snmp_error("bad digest size - %d", olen);
EVP_MD_CTX_cleanup(&ctx);
return (SNMP_CODE_BADDIGEST);
}
memcpy(digest, md, SNMP_USM_AUTH_SIZE);
EVP_MD_CTX_cleanup(&ctx);
return (SNMP_CODE_OK);
failed:
EVP_MD_CTX_cleanup(&ctx);
return (SNMP_CODE_BADDIGEST);
}
static int32_t
snmp_pdu_cipher_init(const struct snmp_pdu *pdu, int32_t len,
EVP_CIPHER_CTX *ctx, const EVP_CIPHER **ctype, uint8_t *piv)
{
int i;
uint32_t netint;
if (pdu->user.priv_proto == SNMP_PRIV_DES) {
if (len % 8 != 0)
return (-1);
*ctype = EVP_des_cbc();
memcpy(piv, pdu->msg_salt, sizeof(pdu->msg_salt));
for (i = 0; i < 8; i++)
piv[i] = piv[i] ^ pdu->user.priv_key[8 + i];
} else if (pdu->user.priv_proto == SNMP_PRIV_AES) {
*ctype = EVP_aes_128_cfb128();
netint = htonl(pdu->engine.engine_boots);
memcpy(piv, &netint, sizeof(netint));
piv += sizeof(netint);
netint = htonl(pdu->engine.engine_time);
memcpy(piv, &netint, sizeof(netint));
piv += sizeof(netint);
memcpy(piv, pdu->msg_salt, sizeof(pdu->msg_salt));
} else if (pdu->user.priv_proto == SNMP_PRIV_NOPRIV)
return (0);
else {
snmp_error("unknown privacy option - %d", pdu->user.priv_proto);
return (-1);
}
return (1);
}
enum snmp_code
snmp_pdu_encrypt(struct asn_buf *b, const struct snmp_pdu *pdu)
{
int32_t err, olen;
uint8_t iv[SNMP_PRIV_AES_IV_SIZ];
const EVP_CIPHER *ctype;
EVP_CIPHER_CTX ctx;
err = snmp_pdu_cipher_init(pdu, pdu->scoped_len, &ctx, &ctype, iv);
if (err < 0)
return (SNMP_CODE_EDECRYPT);
else if (err == 0)
return (SNMP_CODE_OK);
if (EVP_EncryptInit(&ctx, ctype, pdu->user.priv_key, iv) != 1)
return (SNMP_CODE_FAILED);
if (EVP_EncryptUpdate(&ctx, pdu->scoped_ptr, &olen, pdu->scoped_ptr,
pdu->scoped_len) != 1 ||
EVP_EncryptFinal(&ctx, pdu->scoped_ptr + olen, &olen) != 1) {
EVP_CIPHER_CTX_cleanup(&ctx);
return (SNMP_CODE_FAILED);
}
EVP_CIPHER_CTX_cleanup(&ctx);
return (SNMP_CODE_OK);
}
enum snmp_code
snmp_pdu_decrypt(struct asn_buf *b, const struct snmp_pdu *pdu)
{
int32_t err, olen;
uint8_t iv[SNMP_PRIV_AES_IV_SIZ];
const EVP_CIPHER *ctype;
EVP_CIPHER_CTX ctx;
err = snmp_pdu_cipher_init(pdu, pdu->scoped_len, &ctx, &ctype, iv);
if (err < 0)
return (SNMP_CODE_EDECRYPT);
else if (err == 0)
return (SNMP_CODE_OK);
if (EVP_DecryptInit(&ctx, ctype, pdu->user.priv_key, iv) != 1 ||
EVP_CIPHER_CTX_set_padding(&ctx, 0) != 1)
return (SNMP_CODE_EDECRYPT);
if (EVP_DecryptUpdate(&ctx, pdu->scoped_ptr, &olen, pdu->scoped_ptr,
pdu->scoped_len) != 1 ||
EVP_DecryptFinal(&ctx, pdu->scoped_ptr + olen, &olen) != 1) {
EVP_CIPHER_CTX_cleanup(&ctx);
return (SNMP_CODE_EDECRYPT);
}
EVP_CIPHER_CTX_cleanup(&ctx);
return (SNMP_CODE_OK);
}
/* [RFC 3414] - A.2. Password to Key Algorithm */
enum snmp_code
snmp_passwd_to_keys(struct snmp_user *user, char *passwd)
{
int err, loop, i, pwdlen;
uint32_t keylen, olen;
const EVP_MD *dtype;
EVP_MD_CTX ctx;
uint8_t authbuf[SNMP_AUTH_BUF_SIZE];
if (passwd == NULL || user == NULL)
return (SNMP_CODE_FAILED);
err = snmp_digest_init(user, &ctx, &dtype, &keylen);
if (err < 0)
return (SNMP_CODE_BADDIGEST);
else if (err == 0)
return (SNMP_CODE_OK);
memset(user->auth_key, 0, sizeof(user->auth_key));
pwdlen = strlen(passwd);
for (loop = 0; loop < SNMP_AUTH_KEY_LOOPCNT; loop += i) {
for (i = 0; i < SNMP_EXTENDED_KEY_SIZ; i++)
authbuf[i] = passwd[(loop + i) % pwdlen];
if (EVP_DigestUpdate(&ctx, authbuf, SNMP_EXTENDED_KEY_SIZ) != 1)
goto failed;
}
if (EVP_DigestFinal(&ctx, user->auth_key, &olen) != 1)
goto failed;
EVP_MD_CTX_cleanup(&ctx);
return (SNMP_CODE_OK);
failed:
EVP_MD_CTX_cleanup(&ctx);
return (SNMP_CODE_BADDIGEST);
}
/* [RFC 3414] - 2.6. Key Localization Algorithm */
enum snmp_code
snmp_get_local_keys(struct snmp_user *user, uint8_t *eid, uint32_t elen)
{
int err;
uint32_t keylen, olen;
const EVP_MD *dtype;
EVP_MD_CTX ctx;
uint8_t authbuf[SNMP_AUTH_BUF_SIZE];
if (user == NULL || eid == NULL || elen > SNMP_ENGINE_ID_SIZ)
return (SNMP_CODE_FAILED);
memset(user->priv_key, 0, sizeof(user->priv_key));
memset(authbuf, 0, sizeof(authbuf));
err = snmp_digest_init(user, &ctx, &dtype, &keylen);
if (err < 0)
return (SNMP_CODE_BADDIGEST);
else if (err == 0)
return (SNMP_CODE_OK);
memcpy(authbuf, user->auth_key, keylen);
memcpy(authbuf + keylen, eid, elen);
memcpy(authbuf + keylen + elen, user->auth_key, keylen);
if (EVP_DigestUpdate(&ctx, authbuf, 2 * keylen + elen) != 1 ||
EVP_DigestFinal(&ctx, user->auth_key, &olen) != 1) {
EVP_MD_CTX_cleanup(&ctx);
return (SNMP_CODE_BADDIGEST);
}
EVP_MD_CTX_cleanup(&ctx);
if (user->priv_proto != SNMP_PRIV_NOPRIV)
memcpy(user->priv_key, user->auth_key, sizeof(user->priv_key));
return (SNMP_CODE_OK);
}
enum snmp_code
snmp_calc_keychange(struct snmp_user *user, uint8_t *keychange)
{
int32_t i, err, rvalue[SNMP_AUTH_HMACSHA_KEY_SIZ / 4];
uint32_t keylen, olen;
const EVP_MD *dtype;
EVP_MD_CTX ctx;
err = snmp_digest_init(user, &ctx, &dtype, &keylen);
if (err < 0)
return (SNMP_CODE_BADDIGEST);
else if (err == 0)
return (SNMP_CODE_OK);
for (i = 0; i < keylen / 4; i++)
rvalue[i] = random();
memcpy(keychange, user->auth_key, keylen);
memcpy(keychange + keylen, rvalue, keylen);
if (EVP_DigestUpdate(&ctx, keychange, 2 * keylen) != 1 ||
EVP_DigestFinal(&ctx, keychange, &olen) != 1) {
EVP_MD_CTX_cleanup(&ctx);
return (SNMP_CODE_BADDIGEST);
}
EVP_MD_CTX_cleanup(&ctx);
return (SNMP_CODE_OK);
}
#else /* !HAVE_LIBCRYPTO */
enum snmp_code
snmp_pdu_calc_digest(struct asn_buf *b __unused, const struct snmp_pdu *pdu,
uint8_t *digest __unused)
{
if (pdu->user.auth_proto != SNMP_AUTH_NOAUTH)
return (SNMP_CODE_BADSECLEVEL);
return (SNMP_CODE_OK);
}
enum snmp_code
snmp_pdu_encrypt(struct asn_buf *b __unused, const struct snmp_pdu *pdu)
{
if (pdu->user.priv_proto != SNMP_PRIV_NOPRIV)
return (SNMP_CODE_BADSECLEVEL);
return (SNMP_CODE_OK);
}
enum snmp_code
snmp_pdu_decrypt(struct asn_buf *b __unused, const struct snmp_pdu *pdu)
{
if (pdu->user.priv_proto != SNMP_PRIV_NOPRIV)
return (SNMP_CODE_BADSECLEVEL);
return (SNMP_CODE_OK);
}
int
snmp_passwd_to_keys(struct snmp_user *user, char *passwd __unused)
{
if (user->auth_proto == SNMP_AUTH_NOAUTH &&
user->priv_proto == SNMP_PRIV_NOPRIV)
return (SNMP_CODE_OK);
errno = EPROTONOSUPPORT;
return (SNMP_CODE_FAILED);
}
int
snmp_get_local_keys(struct snmp_user *user, uint8_t *eid __unused,
uint32_t elen __unused)
{
if (user->auth_proto == SNMP_AUTH_NOAUTH &&
user->priv_proto == SNMP_PRIV_NOPRIV)
return (SNMP_CODE_OK);
errno = EPROTONOSUPPORT;
return (SNMP_CODE_FAILED);
}
enum snmp_code
snmp_calc_keychange(struct snmp_user *user __unused,
uint8_t *keychange __unused)
{
errno = EPROTONOSUPPORT;
return (SNMP_CODE_FAILED);
}
#endif /* HAVE_LIBCRYPTO */

View File

@ -34,12 +34,18 @@
enum asn_err snmp_binding_encode(struct asn_buf *, const struct snmp_value *);
enum snmp_code snmp_pdu_encode_header(struct asn_buf *, struct snmp_pdu *);
enum snmp_code snmp_fix_encoding(struct asn_buf *, const struct snmp_pdu *);
enum asn_err snmp_parse_message_hdr(struct asn_buf *b, struct snmp_pdu *pdu,
asn_len_t *lenp);
enum snmp_code snmp_fix_encoding(struct asn_buf *, struct snmp_pdu *);
enum asn_err snmp_parse_pdus_hdr(struct asn_buf *b, struct snmp_pdu *pdu,
asn_len_t *lenp);
void snmp_pdu_init_secparams(struct snmp_pdu *, struct snmp_engine *,
struct snmp_user *);
enum snmp_code snmp_pdu_calc_digest(struct asn_buf *, const struct snmp_pdu *,
uint8_t *);
enum snmp_code snmp_pdu_encrypt(struct asn_buf *, const struct snmp_pdu *);
enum snmp_code snmp_pdu_decrypt(struct asn_buf *, const struct snmp_pdu *);
#define DEFAULT_HOST "localhost"
#define DEFAULT_PORT "snmp"
#define DEFAULT_LOCAL "/var/run/snmp.sock"

132
contrib/bsnmp/snmp_usm/snmp_usm.3 Executable file
View File

@ -0,0 +1,132 @@
.\"-
.\" Copyright (C) 2010 The FreeBSD Foundation
.\" All rights reserved.
.\"
.\" This documentation was written by Shteryana Sotirova Shopova under
.\" sponsorship from the FreeBSD Foundation.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD$
.\"
.Dd September 9, 2010
.Dt SNMP_USM 3
.Os
.Sh NAME
.Nm snmp_usm
.Nd "user-based security module for
.Xr bsnmpd 1
.Sh LIBRARY
.Pq begemotSnmpdModulePath."usm" = "/usr/lib/snmp_usm.so"
.Sh DESCRIPTION
The
.Nm snmp_usm
module implements SNMPv3 User-Based Security Model MIB as defined in RFC 3414.
The module is used to manage the internal list of SNMPv3 USM active users in
.Nm bsnmpd .
The module must be loaded for
.Nm bsnmpd
to receive and process SNMPv3 USM PDUs correctly.
.Sh IMPLEMENTATION NOTES
A short description of the objects in the MIB follows.
.Bl -tag -width "XXXXXXXXX"
.It Va usmStats
The subtree contains statistics for the User-based Security Model PDU processing.
The statistics are reset each time the module is loaded.
.It Va usmUserSpinLock
An advisory lock used to coordinate several Command Generator Applications when
altering the SNMP USM users.
.It Va usmUserTable
The table contains all SNMP USM users configured in
.Nm bsnmpd.
The table contains the following objects
.Bl -tag -width ".It Va usmUserEngineID"
.It Va usmUserEngineID
An SNMP engine's administratively-unique identifier. Must be set to the same
Engine ID as
.Nm bsnmpd
so that the user will actually be allowed to communicate with the daemon.
The column is used as entry key and is not accessible for GET or SET operations.
.It Va usmUserName
The USM user name. The second entry key, again not accessible for GET or SET
operations.
.It Va usmUserSecurityName
The column has the exact same value as the
.Va usmUserName
column, however is accessible for GET operations.
.It Va usmUserCloneFrom
A GET on this column will return an empty OID. SET operations are currently not
supported.
.It Va usmUserAuthProtocol
The value of this column contains the OID corresponding to the authentication
protocol used by the USM user. The following protocols and their OIDs are known to
.Nm
module
.Bl -tag -width ".It Va NoAuthProtocol"
.It NoAuthProtocol 1.3.6.1.6.3.10.1.1.1
.It HMACMD5AuthProtocol 1.3.6.1.6.3.10.1.1.2
.It HMACSHAAuthProtocol 1.3.6.1.6.3.10.1.1.3
.El
.It Va usmUserAuthKeyChange , Va usmUserOwnAuthKeyChange
These columns may be used to change the user's authentication key.
.It Va usmUserPrivProtocol
The value of this column contains the OID corresponding to the privacy
protocol used by the USM user. The following protocols and their OIDs are known to
.Nm
module
.Bl -tag -width ".It Va NoPrivProtocol"
.It NoPrivProtocol 1.3.6.1.6.3.10.1.2.1
.It DESPrivProtoco 1.3.6.1.6.3.10.1.2.2
.It AesCfb128Protocol 1.3.6.1.6.3.10.1.2.4
.El
.It Va usmUserPrivKeyChange , Va usmUserOwnPrivKeyChange
These columns may be used to change the user's privacy key.
.It Va usmUserPublic
An arbitrary octet string that may be modified to confirm a SET operation on any
of the columns was successfull.
.It Va usmUserStorageType
This column always has either of two values. Entries created via
.Nm bsnmpd's
configuration file always have this column set to readOnly (5) and
it is not possible to modify those entries. Entries created by Command Generator
Applications always have this column set to volatile(2) and such entries are
lost when the module is restarted. A SET operation on this column is not
allowed.
.It Va usmUserStatus
This column is used to create new USM user entries or delete exsiting ones from
the table.
.El
.EL
.Sh FILES
.Bl -tag -width "XXXXXXXXX"
.It Pa /usr/share/snmp/defs/usm_tree.def
The description of the MIB tree implemented by
.Nm .
.El
.Sh SEE ALSO
.Xr bsnmpd 1 ,
.Xr gensnmptree 1 ,
.Xr snmpmod 3
.Sh STANDARDS
IETF RFC 3414
.Sh AUTHORS
.An Shteryana Shopova Aq syrinx@FreeBSD.org

614
contrib/bsnmp/snmp_usm/usm_snmp.c Executable file
View File

@ -0,0 +1,614 @@
/*-
* Copyright (c) 2010 The FreeBSD Foundation
* All rights reserved.
*
* This software was developed by Shteryana Sotirova Shopova under
* sponsorship from the FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#include <sys/queue.h>
#include <sys/types.h>
#include <errno.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <syslog.h>
#include "asn1.h"
#include "snmp.h"
#include "snmpmod.h"
#include "usm_tree.h"
#include "usm_oid.h"
static struct lmodule *usm_module;
/* For the registration. */
static const struct asn_oid oid_usm = OIDX_snmpUsmMIB;
static const struct asn_oid oid_usmNoAuthProtocol = OIDX_usmNoAuthProtocol;
static const struct asn_oid oid_usmHMACMD5AuthProtocol = \
OIDX_usmHMACMD5AuthProtocol;
static const struct asn_oid oid_usmHMACSHAAuthProtocol = \
OIDX_usmHMACSHAAuthProtocol;
static const struct asn_oid oid_usmNoPrivProtocol = OIDX_usmNoPrivProtocol;
static const struct asn_oid oid_usmDESPrivProtocol = OIDX_usmDESPrivProtocol;
static const struct asn_oid oid_usmAesCfb128Protocol = OIDX_usmAesCfb128Protocol;
static const struct asn_oid oid_usmUserSecurityName = OIDX_usmUserSecurityName;
/* The registration. */
static uint reg_usm;
static int32_t usm_lock;
static struct usm_user * usm_get_user(const struct asn_oid *, uint);
static struct usm_user * usm_get_next_user(const struct asn_oid *, uint);
static void usm_append_userindex(struct asn_oid *, uint,
const struct usm_user *);
static int usm_user_index_decode(const struct asn_oid *, uint, uint8_t *,
uint32_t *, char *);
int
op_usm_stats(struct snmp_context *ctx __unused, struct snmp_value *val,
uint32_t sub __unused, uint32_t iidx __unused, enum snmp_op op)
{
struct snmpd_usmstat *usmstats;
if (op == SNMP_OP_SET)
return (SNMP_ERR_NOT_WRITEABLE);
if ((usmstats = bsnmpd_get_usm_stats()) == NULL)
return (SNMP_ERR_GENERR);
if (op == SNMP_OP_GET) {
switch (val->var.subs[sub - 1]) {
case LEAF_usmStatsUnsupportedSecLevels:
val->v.uint32 = usmstats->unsupported_seclevels;
break;
case LEAF_usmStatsNotInTimeWindows:
val->v.uint32 = usmstats->not_in_time_windows;
break;
case LEAF_usmStatsUnknownUserNames:
val->v.uint32 = usmstats->unknown_users;
break;
case LEAF_usmStatsUnknownEngineIDs:
val->v.uint32 = usmstats->unknown_engine_ids;
break;
case LEAF_usmStatsWrongDigests:
val->v.uint32 = usmstats->wrong_digests;
break;
case LEAF_usmStatsDecryptionErrors:
val->v.uint32 = usmstats->decrypt_errors;
break;
default:
return (SNMP_ERR_NOSUCHNAME);
}
return (SNMP_ERR_NOERROR);
}
abort();
}
int
op_usm_lock(struct snmp_context *ctx __unused, struct snmp_value *val,
uint32_t sub, uint32_t iidx __unused, enum snmp_op op)
{
if (val->var.subs[sub - 1] != LEAF_usmUserSpinLock)
return (SNMP_ERR_NOSUCHNAME);
switch (op) {
case SNMP_OP_GET:
if (++usm_lock == INT32_MAX)
usm_lock = 0;
val->v.integer = usm_lock;
break;
case SNMP_OP_GETNEXT:
abort();
case SNMP_OP_SET:
if (val->v.integer != usm_lock)
return (SNMP_ERR_INCONS_VALUE);
break;
case SNMP_OP_ROLLBACK:
/* FALLTHROUGH */
case SNMP_OP_COMMIT:
break;
}
return (SNMP_ERR_NOERROR);
}
int
op_usm_users(struct snmp_context *ctx, struct snmp_value *val,
uint32_t sub, uint32_t iidx __unused, enum snmp_op op)
{
uint32_t elen;
struct usm_user *uuser, *clone;
char uname[SNMP_ADM_STR32_SIZ];
uint8_t eid[SNMP_ENGINE_ID_SIZ];
switch (op) {
case SNMP_OP_GET:
if ((uuser = usm_get_user(&val->var, sub)) == NULL)
return (SNMP_ERR_NOSUCHNAME);
break;
case SNMP_OP_GETNEXT:
if ((uuser = usm_get_next_user(&val->var, sub)) == NULL)
return (SNMP_ERR_NOSUCHNAME);
usm_append_userindex(&val->var, sub, uuser);
break;
case SNMP_OP_SET:
if ((uuser = usm_get_user(&val->var, sub)) == NULL &&
val->var.subs[sub - 1] != LEAF_usmUserStatus &&
val->var.subs[sub - 1] != LEAF_usmUserCloneFrom)
return (SNMP_ERR_NOSUCHNAME);
if (community != COMM_INITIALIZE &&
uuser->type == StorageType_readOnly)
return (SNMP_ERR_NOT_WRITEABLE);
switch (val->var.subs[sub - 1]) {
case LEAF_usmUserSecurityName:
return (SNMP_ERR_NOT_WRITEABLE);
case LEAF_usmUserCloneFrom:
if (uuser != NULL || usm_user_index_decode(&val->var,
sub, eid, &elen, uname) < 0 ||
!(asn_is_suboid(&oid_usmUserSecurityName, &val->v.oid)))
return (SNMP_ERR_WRONG_VALUE);
if ((clone = usm_get_user(&val->v.oid, sub)) == NULL)
return (SNMP_ERR_INCONS_VALUE);
if ((uuser = usm_new_user(eid, elen, uname)) == NULL)
return (SNMP_ERR_GENERR);
uuser->status = RowStatus_notReady;
if (community != COMM_INITIALIZE)
uuser->type = StorageType_volatile;
else
uuser->type = StorageType_readOnly;
uuser->suser.auth_proto = clone->suser.auth_proto;
uuser->suser.priv_proto = clone->suser.priv_proto;
memcpy(uuser->suser.auth_key, clone->suser.auth_key,
sizeof(uuser->suser.auth_key));
memcpy(uuser->suser.priv_key, clone->suser.priv_key,
sizeof(uuser->suser.priv_key));
ctx->scratch->int1 = RowStatus_createAndWait;
break;
case LEAF_usmUserAuthProtocol:
ctx->scratch->int1 = uuser->suser.auth_proto;
if (asn_compare_oid(&oid_usmNoAuthProtocol,
&val->v.oid) == 0)
uuser->suser.auth_proto = SNMP_AUTH_NOAUTH;
else if (asn_compare_oid(&oid_usmHMACMD5AuthProtocol,
&val->v.oid) == 0)
uuser->suser.auth_proto = SNMP_AUTH_HMAC_MD5;
else if (asn_compare_oid(&oid_usmHMACSHAAuthProtocol,
&val->v.oid) == 0)
uuser->suser.auth_proto = SNMP_AUTH_HMAC_SHA;
else
return (SNMP_ERR_WRONG_VALUE);
break;
case LEAF_usmUserAuthKeyChange:
case LEAF_usmUserOwnAuthKeyChange:
if (val->var.subs[sub - 1] ==
LEAF_usmUserOwnAuthKeyChange &&
(usm_user == NULL || strcmp(uuser->suser.sec_name,
usm_user->suser.sec_name) != 0))
return (SNMP_ERR_NO_ACCESS);
if (val->v.octetstring.len > SNMP_AUTH_KEY_SIZ)
return (SNMP_ERR_INCONS_VALUE);
ctx->scratch->ptr1 = malloc(SNMP_AUTH_KEY_SIZ);
if (ctx->scratch->ptr1 == NULL)
return (SNMP_ERR_GENERR);
memcpy(ctx->scratch->ptr1, uuser->suser.auth_key,
SNMP_AUTH_KEY_SIZ);
memcpy(uuser->suser.auth_key, val->v.octetstring.octets,
val->v.octetstring.len);
break;
case LEAF_usmUserPrivProtocol:
ctx->scratch->int1 = uuser->suser.priv_proto;
if (asn_compare_oid(&oid_usmNoPrivProtocol,
&val->v.oid) == 0)
uuser->suser.priv_proto = SNMP_PRIV_NOPRIV;
else if (asn_compare_oid(&oid_usmDESPrivProtocol,
&val->v.oid) == 0)
uuser->suser.priv_proto = SNMP_PRIV_DES;
else if (asn_compare_oid(&oid_usmAesCfb128Protocol,
&val->v.oid) == 0)
uuser->suser.priv_proto = SNMP_PRIV_AES;
else
return (SNMP_ERR_WRONG_VALUE);
break;
case LEAF_usmUserPrivKeyChange:
case LEAF_usmUserOwnPrivKeyChange:
if (val->var.subs[sub - 1] ==
LEAF_usmUserOwnPrivKeyChange &&
(usm_user == NULL || strcmp(uuser->suser.sec_name,
usm_user->suser.sec_name) != 0))
return (SNMP_ERR_NO_ACCESS);
if (val->v.octetstring.len > SNMP_PRIV_KEY_SIZ)
return (SNMP_ERR_INCONS_VALUE);
ctx->scratch->ptr1 = malloc(SNMP_PRIV_KEY_SIZ);
if (ctx->scratch->ptr1 == NULL)
return (SNMP_ERR_GENERR);
memcpy(ctx->scratch->ptr1, uuser->suser.priv_key,
SNMP_PRIV_KEY_SIZ);
memcpy(uuser->suser.priv_key, val->v.octetstring.octets,
val->v.octetstring.len);
break;
case LEAF_usmUserPublic:
if (val->v.octetstring.len > SNMP_ADM_STR32_SIZ)
return (SNMP_ERR_INCONS_VALUE);
if (uuser->user_public_len > 0) {
ctx->scratch->ptr2 =
malloc(uuser->user_public_len);
if (ctx->scratch->ptr2 == NULL)
return (SNMP_ERR_GENERR);
memcpy(ctx->scratch->ptr2, uuser->user_public,
uuser->user_public_len);
ctx->scratch->int2 = uuser->user_public_len;
}
if (val->v.octetstring.len > 0) {
memcpy(uuser->user_public,
val->v.octetstring.octets,
val->v.octetstring.len);
uuser->user_public_len = val->v.octetstring.len;
} else {
memset(uuser->user_public, 0,
SNMP_ADM_STR32_SIZ);
uuser->user_public_len = 0;
}
break;
case LEAF_usmUserStorageType:
return (SNMP_ERR_INCONS_VALUE);
case LEAF_usmUserStatus:
if (uuser == NULL) {
if (val->v.integer != RowStatus_createAndWait ||
usm_user_index_decode(&val->var, sub, eid,
&elen, uname) < 0)
return (SNMP_ERR_INCONS_VALUE);
uuser = usm_new_user(eid, elen, uname);
if (uuser == NULL)
return (SNMP_ERR_GENERR);
uuser->status = RowStatus_notReady;
if (community != COMM_INITIALIZE)
uuser->type = StorageType_volatile;
else
uuser->type = StorageType_readOnly;
} else if (val->v.integer != RowStatus_active &&
val->v.integer != RowStatus_destroy)
return (SNMP_ERR_INCONS_VALUE);
uuser->status = val->v.integer;
break;
}
return (SNMP_ERR_NOERROR);
case SNMP_OP_COMMIT:
switch (val->var.subs[sub - 1]) {
case LEAF_usmUserAuthKeyChange:
case LEAF_usmUserOwnAuthKeyChange:
case LEAF_usmUserPrivKeyChange:
case LEAF_usmUserOwnPrivKeyChange:
free(ctx->scratch->ptr1);
break;
case LEAF_usmUserPublic:
if (ctx->scratch->ptr2 != NULL)
free(ctx->scratch->ptr2);
break;
case LEAF_usmUserStatus:
if (val->v.integer != RowStatus_destroy)
break;
if ((uuser = usm_get_user(&val->var, sub)) == NULL)
return (SNMP_ERR_GENERR);
usm_delete_user(uuser);
break;
default:
break;
}
return (SNMP_ERR_NOERROR);
case SNMP_OP_ROLLBACK:
if ((uuser = usm_get_user(&val->var, sub)) == NULL)
return (SNMP_ERR_GENERR);
switch (val->var.subs[sub - 1]) {
case LEAF_usmUserAuthProtocol:
uuser->suser.auth_proto = ctx->scratch->int1;
break;
case LEAF_usmUserAuthKeyChange:
case LEAF_usmUserOwnAuthKeyChange:
memcpy(uuser->suser.auth_key, ctx->scratch->ptr1,
SNMP_AUTH_KEY_SIZ);
free(ctx->scratch->ptr1);
break;
case LEAF_usmUserPrivProtocol:
uuser->suser.priv_proto = ctx->scratch->int1;
break;
case LEAF_usmUserPrivKeyChange:
case LEAF_usmUserOwnPrivKeyChange:
memcpy(uuser->suser.priv_key, ctx->scratch->ptr1,
SNMP_AUTH_KEY_SIZ);
free(ctx->scratch->ptr1);
break;
case LEAF_usmUserPublic:
if (ctx->scratch->ptr2 != NULL) {
memcpy(uuser->user_public, ctx->scratch->ptr2,
ctx->scratch->int2);
uuser->user_public_len = ctx->scratch->int2;
free(ctx->scratch->ptr2);
} else {
memset(uuser->user_public, 0,
SNMP_ADM_STR32_SIZ);
uuser->user_public_len = 0;
}
break;
case LEAF_usmUserCloneFrom:
case LEAF_usmUserStatus:
if (ctx->scratch->int1 == RowStatus_createAndWait)
usm_delete_user(uuser);
break;
default:
break;
}
return (SNMP_ERR_NOERROR);
default:
abort();
}
switch (val->var.subs[sub - 1]) {
case LEAF_usmUserSecurityName:
return (string_get(val, uuser->suser.sec_name, -1));
case LEAF_usmUserCloneFrom:
memcpy(&val->v.oid, &oid_zeroDotZero, sizeof(oid_zeroDotZero));
break;
case LEAF_usmUserAuthProtocol:
switch (uuser->suser.auth_proto) {
case SNMP_AUTH_HMAC_MD5:
memcpy(&val->v.oid, &oid_usmHMACMD5AuthProtocol,
sizeof(oid_usmHMACMD5AuthProtocol));
break;
case SNMP_AUTH_HMAC_SHA:
memcpy(&val->v.oid, &oid_usmHMACSHAAuthProtocol,
sizeof(oid_usmHMACSHAAuthProtocol));
break;
default:
memcpy(&val->v.oid, &oid_usmNoAuthProtocol,
sizeof(oid_usmNoAuthProtocol));
break;
}
break;
case LEAF_usmUserAuthKeyChange:
case LEAF_usmUserOwnAuthKeyChange:
return (string_get(val, (char *)uuser->suser.auth_key, 0));
case LEAF_usmUserPrivProtocol:
switch (uuser->suser.priv_proto) {
case SNMP_PRIV_DES:
memcpy(&val->v.oid, &oid_usmDESPrivProtocol,
sizeof(oid_usmDESPrivProtocol));
break;
case SNMP_PRIV_AES:
memcpy(&val->v.oid, &oid_usmAesCfb128Protocol,
sizeof(oid_usmAesCfb128Protocol));
break;
default:
memcpy(&val->v.oid, &oid_usmNoPrivProtocol,
sizeof(oid_usmNoPrivProtocol));
break;
}
break;
case LEAF_usmUserPrivKeyChange:
case LEAF_usmUserOwnPrivKeyChange:
return (string_get(val, (char *)uuser->suser.priv_key, 0));
case LEAF_usmUserPublic:
return (string_get(val, uuser->user_public,
uuser->user_public_len));
case LEAF_usmUserStorageType:
val->v.integer = uuser->type;
break;
case LEAF_usmUserStatus:
val->v.integer = uuser->status;
break;
}
return (SNMP_ERR_NOERROR);
}
static int
usm_user_index_decode(const struct asn_oid *oid, uint sub, uint8_t *engine,
uint32_t *elen, char *uname)
{
uint32_t i, nlen;
int uname_off;
if (oid->subs[sub] > SNMP_ENGINE_ID_SIZ)
return (-1);
for (i = 0; i < oid->subs[sub]; i++)
engine[i] = oid->subs[sub + i + 1];
*elen = i;
uname_off = sub + oid->subs[sub] + 1;
if ((nlen = oid->subs[uname_off]) >= SNMP_ADM_STR32_SIZ)
return (-1);
for (i = 0; i < nlen; i++)
uname[i] = oid->subs[uname_off + i + 1];
uname[nlen] = '\0';
return (0);
}
static void
usm_append_userindex(struct asn_oid *oid, uint sub,
const struct usm_user *uuser)
{
uint32_t i;
oid->len = sub + uuser->user_engine_len + strlen(uuser->suser.sec_name);
oid->len += 2;
oid->subs[sub] = uuser->user_engine_len;
for (i = 1; i < uuser->user_engine_len + 1; i++)
oid->subs[sub + i] = uuser->user_engine_id[i - 1];
sub += uuser->user_engine_len + 1;
oid->subs[sub] = strlen(uuser->suser.sec_name);
for (i = 1; i <= oid->subs[sub]; i++)
oid->subs[sub + i] = uuser->suser.sec_name[i - 1];
}
static struct usm_user *
usm_get_user(const struct asn_oid *oid, uint sub)
{
uint32_t enginelen;
char username[SNMP_ADM_STR32_SIZ];
uint8_t engineid[SNMP_ENGINE_ID_SIZ];
if (usm_user_index_decode(oid, sub, engineid, &enginelen, username) < 0)
return (NULL);
return (usm_find_user(engineid, enginelen, username));
}
static struct usm_user *
usm_get_next_user(const struct asn_oid *oid, uint sub)
{
uint32_t enginelen;
char username[SNMP_ADM_STR32_SIZ];
uint8_t engineid[SNMP_ENGINE_ID_SIZ];
struct usm_user *uuser;
if (oid->len - sub == 0)
return (usm_first_user());
if (usm_user_index_decode(oid, sub, engineid, &enginelen, username) < 0)
return (NULL);
if ((uuser = usm_find_user(engineid, enginelen, username)) != NULL)
return (usm_next_user(uuser));
return (NULL);
}
/*
* USM snmp module initialization hook.
* Returns 0 on success, < 0 on error.
*/
static int
usm_init(struct lmodule * mod, int argc __unused, char *argv[] __unused)
{
usm_module = mod;
usm_lock = random();
bsnmpd_reset_usm_stats();
return (0);
}
/*
* USM snmp module finalization hook.
*/
static int
usm_fini(void)
{
usm_flush_users();
or_unregister(reg_usm);
return (0);
}
/*
* USM snmp module start operation.
*/
static void
usm_start(void)
{
reg_usm = or_register(&oid_usm,
"The MIB module for managing SNMP User-Based Security Model.",
usm_module);
}
static void
usm_dump(void)
{
struct usm_user *uuser;
struct snmpd_usmstat *usmstats;
const char *const authstr[] = {
"noauth",
"md5",
"sha",
NULL
};
const char *const privstr[] = {
"nopriv",
"des",
"aes",
NULL
};
if ((usmstats = bsnmpd_get_usm_stats()) != NULL) {
syslog(LOG_ERR, "UnsupportedSecLevels\t\t%u",
usmstats->unsupported_seclevels);
syslog(LOG_ERR, "NotInTimeWindows\t\t%u",
usmstats->not_in_time_windows);
syslog(LOG_ERR, "UnknownUserNames\t\t%u",
usmstats->unknown_users);
syslog(LOG_ERR, "UnknownEngineIDs\t\t%u",
usmstats->unknown_engine_ids);
syslog(LOG_ERR, "WrongDigests\t\t%u",
usmstats->wrong_digests);
syslog(LOG_ERR, "DecryptionErrors\t\t%u",
usmstats->decrypt_errors);
}
syslog(LOG_ERR, "USM users");
for (uuser = usm_first_user(); uuser != NULL;
(uuser = usm_next_user(uuser)))
syslog(LOG_ERR, "user %s\t\t%s, %s", uuser->suser.sec_name,
authstr[uuser->suser.auth_proto],
privstr[uuser->suser.priv_proto]);
}
const char usm_comment[] = \
"This module implements SNMP User-based Security Model defined in RFC 3414.";
const struct snmp_module config = {
.comment = usm_comment,
.init = usm_init,
.fini = usm_fini,
.start = usm_start,
.tree = usm_ctree,
.dump = usm_dump,
.tree_size = usm_CTREE_SIZE,
};

View File

@ -0,0 +1,109 @@
#-
# Copyright (C) 2010 The FreeBSD Foundation
# All rights reserved.
#
# This software was developed by Shteryana Sotirova Shopova under
# sponsorship from the FreeBSD Foundation.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# $FreeBSD$
#
typedef StorageType ENUM (
1 other
2 volatile
3 nonVolatile
4 permanent
5 readOnly
)
typedef RowStatus ENUM (
1 active
2 notInService
3 notReady
4 createAndGo
5 createAndWait
6 destroy
)
(1 internet
(6 snmpV2
(3 snmpModules
(10 snmpFrameworkMIB
(1 snmpFrameworkAdmin
(1 snmpAuthProtocols
(1 usmNoAuthProtocol
)
(2 usmHMACMD5AuthProtocol
)
(3 usmHMACSHAAuthProtocol
)
)
(2 snmpPrivProtocols
(1 usmNoPrivProtocol
)
(2 usmDESPrivProtocol
)
(4 usmAesCfb128Protocol
)
)
)
)
(15 snmpUsmMIB
(1 usmMIBObjects
(1 usmStats
(1 usmStatsUnsupportedSecLevels COUNTER op_usm_stats GET)
(2 usmStatsNotInTimeWindows COUNTER op_usm_stats GET)
(3 usmStatsUnknownUserNames COUNTER op_usm_stats GET)
(4 usmStatsUnknownEngineIDs COUNTER op_usm_stats GET)
(5 usmStatsWrongDigests COUNTER op_usm_stats GET)
(6 usmStatsDecryptionErrors COUNTER op_usm_stats GET)
)
(2 usmUser
(1 usmUserSpinLock INTEGER op_usm_lock GET SET)
(2 usmUserTable
(1 usmUserEntry : OCTETSTRING | SnmpEngineID OCTETSTRING op_usm_users
(1 usmUserEngineID OCTETSTRING | SnmpEngineID)
(2 usmUserName OCTETSTRING)
(3 usmUserSecurityName OCTETSTRING | SnmpAdminString GET)
(4 usmUserCloneFrom OID GET SET)
(5 usmUserAuthProtocol OID GET SET)
(6 usmUserAuthKeyChange OCTETSTRING | KeyChange GET SET)
(7 usmUserOwnAuthKeyChange OCTETSTRING | KeyChange GET SET)
(8 usmUserPrivProtocol OID GET SET)
(9 usmUserPrivKeyChange OCTETSTRING | KeyChange GET SET)
(10 usmUserOwnPrivKeyChange OCTETSTRING | KeyChange GET SET)
(11 usmUserPublic OCTETSTRING GET SET)
(12 usmUserStorageType StorageType GET SET)
(13 usmUserStatus RowStatus GET SET)
)
)
)
)
)
(20 snmpUsmAesMIB
)
)
)
)

View File

@ -0,0 +1,94 @@
.\"-
.\" Copyright (C) 2010 The FreeBSD Foundation
.\" All rights reserved.
.\"
.\" This documentation was written by Shteryana Sotirova Shopova under
.\" sponsorship from the FreeBSD Foundation.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD$
.\"
.Dd October 7, 2010
.Dt SNMP_VACM 3
.Os
.Sh NAME
.Nm snmp_vacm
.Nd "View-based Access Control module for
.Xr bsnmpd 1
.Sh LIBRARY
.Pq begemotSnmpdModulePath."vacm" = "/usr/lib/snmp_vacm.so"
.Sh DESCRIPTION
The
.Nm snmp_vacm
module implements SNMPv3 View-based Access Control Model MIB as defined in
RFC 3415. The module is used to manage the internal lists of SNMPv1, v2c and
v3 user names and groups and their access rights to fetch or modify the values
of the MIB objects maintained by
.Nm bsnmpd
and the modules loaded in the daemon.
The module must be loaded for
.Nm bsnmpd
to implement proper view-based access control. If the module is not loaded,
access is granted to all configured SNMPv1 & SNMPv2c communities and SNMPv3
USM users.
.Sh IMPLEMENTATION NOTES
An entry in any table implemented by this MIB may be created by setting the
relevant RowStatus column to createAndGo (4) - in fact, any other value for
those columns in a SET operation will cause an error. When an entry is created,
any of its columns that is not used as index, is set to the default value as
specified in the SNMP-VIEW-BASED-ACM-MIB. All entries maintained by the module
are persistent after reboot if created via
.Nm bsnmpd 's
config file, otherwise entries created via SNMP are lost after reboot.
A short description of the objects in the MIB follows.
.Bl -tag -width "XXXXXXXXX"
.It Va vacmContextTable
A read-only table that consists of a list of SNMP contexts available in
.Nm bsnmpd .
.It Va vacmSecurityToGroupTable
The table contains a list of SNMPv1, v2c and v3 user names and the groups
they belong to.
.It Va vacmAccessTable
The table contains a list of SNMP contexts to groups mappings and respectively
the names of the SNMP views under those contexts, to which users in the group
are granted read-only, read-write access or receive notifications for the
objects under the subtree in the relevant view.
.It Va vacmViewTreeFamilyTable
The table contains a list of SNMP views, i.e. entries specifying the OID of a
MIB subtree and whether access to the objects under this subtree is to be
allowed or forbiden.
.El
.Sh FILES
.Bl -tag -width "XXXXXXXXX"
.It Pa /usr/share/snmp/defs/vacm_tree.def
The description of the MIB tree implemented by
.Nm .
.El
.Sh SEE ALSO
.Xr bsnmpd 1 ,
.Xr gensnmptree 1 ,
.Xr snmpmod 3
.Sh STANDARDS
IETF RFC 3415
.Sh AUTHORS
.An Shteryana Shopova Aq syrinx@FreeBSD.org

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,104 @@
#-
# Copyright (C) 2010 The FreeBSD Foundation
# All rights reserved.
#
# This software was developed by Shteryana Sotirova Shopova under
# sponsorship from the FreeBSD Foundation.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# $FreeBSD$
#
typedef StorageType ENUM (
1 other
2 volatile
3 nonVolatile
4 permanent
5 readOnly
)
typedef RowStatus ENUM (
1 active
2 notInService
3 notReady
4 createAndGo
5 createAndWait
6 destroy
)
(1 internet
(6 snmpV2
(3 snmpModules
(16 snmpVacmMIB
(1 vacmMIBObjects
(1 vacmContextTable
(1 vacmContextEntry : OCTETSTRING op_vacm_context
(1 vacmContextName OCTETSTRING GET)
)
)
(2 vacmSecurityToGroupTable
(1 vacmSecurityToGroupEntry : INTEGER OCTETSTRING op_vacm_security_to_group
(1 vacmSecurityModel INTEGER)
(2 vacmSecurityName OCTETSTRING)
(3 vacmGroupName OCTETSTRING GET SET)
(4 vacmSecurityToGroupStorageType StorageType GET SET)
(5 vacmSecurityToGroupStatus RowStatus GET SET)
)
)
(4 vacmAccessTable
(1 vacmAccessEntry : OCTETSTRING OCTETSTRING INTEGER ENUM ( 1 noAuthNoPriv 2 authNoPriv 3 authPriv ) op_vacm_access
(1 vacmAccessContextPrefix OCTETSTRING)
(2 vacmAccessSecurityModel INTEGER)
(3 vacmAccessSecurityLevel ENUM ( 1 noAuthNoPriv 2 authNoPriv 3 authPriv ))
(4 vacmAccessContextMatch ENUM ( 1 exact 2 prefix ) GET SET)
(5 vacmAccessReadViewName OCTETSTRING GET SET)
(6 vacmAccessWriteViewName OCTETSTRING GET SET)
(7 vacmAccessNotifyViewName OCTETSTRING GET SET)
(8 vacmAccessStorageType StorageType GET SET)
(9 vacmAccessStatus RowStatus GET SET)
)
)
(5 vacmMIBViews
(1 vacmViewSpinLock INTEGER op_vacm_view_lock GET SET)
(2 vacmViewTreeFamilyTable
(1 vacmViewTreeFamilyEntry : OCTETSTRING OID op_vacm_view
(1 vacmViewTreeFamilyViewName OCTETSTRING)
(2 vacmViewTreeFamilySubtree OID)
(3 vacmViewTreeFamilyMask OCTETSTRING GET SET)
(4 vacmViewTreeFamilyType ENUM ( 1 included 2 excluded ) GET SET)
(5 vacmViewTreeFamilyStorageType StorageType GET SET)
(6 vacmViewTreeFamilyStatus RowStatus GET SET)
)
)
)
)
(2 vacmMIBConformance
(1 vacmMIBCompliances
)
(2 vacmMIBGroups
)
)
)
)
)
)

View File

@ -139,7 +139,8 @@ begemotSnmpdVersionEnable OBJECT-TYPE
bits are defined:
0x00000001 - SNMPv1
0x00000002 - SNMPv2c"
0x00000002 - SNMPv2c
0x00000004 - SNMPv3"
DEFVAL { 3 }
::= { begemotSnmpdConfig 5 }

View File

@ -34,6 +34,7 @@
* Variable access for SNMPd
*/
#include <sys/types.h>
#include <sys/queue.h>
#include <sys/sysctl.h>
#include <sys/un.h>
#include <sys/utsname.h>
@ -42,6 +43,7 @@
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <syslog.h>
#include "snmpmod.h"
@ -162,7 +164,83 @@ init_actvals(void)
return (0);
}
/*
* Initialize global variables of the snmpEngine group.
*/
int
init_snmpd_engine(void)
{
char *hostid;
snmpd_engine.engine_boots = 1;
snmpd_engine.engine_time = 1;
snmpd_engine.max_msg_size = 1500; /* XXX */
snmpd_engine.engine_id[0] = ((OID_freeBSD & 0xff000000) >> 24) | 0x80;
snmpd_engine.engine_id[1] = (OID_freeBSD & 0xff0000) >> 16;
snmpd_engine.engine_id[2] = (OID_freeBSD & 0xff00) >> 8;
snmpd_engine.engine_id[3] = OID_freeBSD & 0xff;
snmpd_engine.engine_id[4] = 128;
snmpd_engine.engine_len = 5;
if ((hostid = act_getkernint(KERN_HOSTID)) == NULL)
return (-1);
if (strlen(hostid) > SNMP_ENGINE_ID_SIZ - snmpd_engine.engine_len) {
memcpy(snmpd_engine.engine_id + snmpd_engine.engine_len,
hostid, SNMP_ENGINE_ID_SIZ - snmpd_engine.engine_len);
snmpd_engine.engine_len = SNMP_ENGINE_ID_SIZ;
} else {
memcpy(snmpd_engine.engine_id + snmpd_engine.engine_len,
hostid, strlen(hostid));
snmpd_engine.engine_len += strlen(hostid);
}
free(hostid);
return (0);
}
int
set_snmpd_engine(void)
{
FILE *fp;
uint32_t i;
uint8_t *cptr, engine[2 * SNMP_ENGINE_ID_SIZ + 2];
uint8_t myengine[2 * SNMP_ENGINE_ID_SIZ + 2];
if (engine_file[0] == '\0')
return (-1);
cptr = myengine;
for (i = 0; i < snmpd_engine.engine_len; i++)
cptr += sprintf(cptr, "%.2x", snmpd_engine.engine_id[i]);
*cptr++ = '\n';
*cptr++ = '\0';
if ((fp = fopen(engine_file, "r+")) != NULL) {
if (fgets(engine, sizeof(engine) - 1, fp) == NULL ||
fscanf(fp, "%u", &snmpd_engine.engine_boots) <= 0) {
fclose(fp);
goto save_boots;
}
fclose(fp);
if (strcmp(myengine, engine) != 0)
snmpd_engine.engine_boots = 1;
else
snmpd_engine.engine_boots++;
} else if (errno != ENOENT)
return (-1);
save_boots:
if ((fp = fopen(engine_file, "w+")) == NULL)
return (-1);
fprintf(fp, "%s%u\n", myengine, snmpd_engine.engine_boots);
fclose(fp);
return (0);
}
/*************************************************************
*
@ -979,6 +1057,103 @@ op_snmp_set(struct snmp_context *ctx __unused, struct snmp_value *value,
abort();
}
/*
* SNMP Engine
*/
int
op_snmp_engine(struct snmp_context *ctx __unused, struct snmp_value *value,
u_int sub, u_int iidx __unused, enum snmp_op op)
{
asn_subid_t which = value->var.subs[sub - 1];
switch (op) {
case SNMP_OP_GETNEXT:
abort();
case SNMP_OP_GET:
break;
case SNMP_OP_SET:
if (community != COMM_INITIALIZE)
return (SNMP_ERR_NOT_WRITEABLE);
switch (which) {
case LEAF_snmpEngineID:
if (value->v.octetstring.len > SNMP_ENGINE_ID_SIZ)
return (SNMP_ERR_WRONG_VALUE);
ctx->scratch->ptr1 = malloc(snmpd_engine.engine_len);
if (ctx->scratch->ptr1 == NULL)
return (SNMP_ERR_GENERR);
memcpy(ctx->scratch->ptr1, snmpd_engine.engine_id,
snmpd_engine.engine_len);
ctx->scratch->int1 = snmpd_engine.engine_len;
snmpd_engine.engine_len = value->v.octetstring.len;
memcpy(snmpd_engine.engine_id,
value->v.octetstring.octets,
value->v.octetstring.len);
break;
case LEAF_snmpEngineMaxMessageSize:
ctx->scratch->int1 = snmpd_engine.max_msg_size;
snmpd_engine.max_msg_size = value->v.integer;
break;
default:
return (SNMP_ERR_NOT_WRITEABLE);
}
return (SNMP_ERR_NOERROR);
case SNMP_OP_ROLLBACK:
switch (which) {
case LEAF_snmpEngineID:
snmpd_engine.engine_len = ctx->scratch->int1;
memcpy(snmpd_engine.engine_id, ctx->scratch->ptr1,
snmpd_engine.engine_len);
free(ctx->scratch->ptr1);
break;
case LEAF_snmpEngineMaxMessageSize:
snmpd_engine.max_msg_size = ctx->scratch->int1;
break;
default:
abort();
}
return (SNMP_ERR_NOERROR);
case SNMP_OP_COMMIT:
if (which == LEAF_snmpEngineID) {
if (set_snmpd_engine() < 0) {
snmpd_engine.engine_len = ctx->scratch->int1;
memcpy(snmpd_engine.engine_id,
ctx->scratch->ptr1, ctx->scratch->int1);
}
free(ctx->scratch->ptr1);
}
return (SNMP_ERR_NOERROR);
}
switch (which) {
case LEAF_snmpEngineID:
return (string_get(value, snmpd_engine.engine_id,
snmpd_engine.engine_len));
case LEAF_snmpEngineBoots:
value->v.integer = snmpd_engine.engine_boots;
break;
case LEAF_snmpEngineTime:
snmpd_engine.engine_time = (get_ticks() - start_tick) / 100ULL;
value->v.integer = snmpd_engine.engine_time;
break;
case LEAF_snmpEngineMaxMessageSize:
value->v.integer = snmpd_engine.max_msg_size;
break;
default:
return (SNMP_ERR_NOSUCHNAME);
}
return (SNMP_ERR_NOERROR);
}
/*
* Transport table
*/

View File

@ -31,7 +31,7 @@
.\"
.\" $Begemot: bsnmp/snmpd/bsnmpd.1,v 1.12 2006/02/27 09:50:03 brandt_h Exp $
.\"
.Dd October 23, 2010
.Dd September 9, 2010
.Dt BSNMPD 1
.Os
.Sh NAME
@ -42,6 +42,7 @@
.Op Fl dh
.Op Fl c Ar file
.Op Fl D Ar options
.Op Fl e Ar file
.Op Fl I Ar paths
.Op Fl l Ar prefix
.Op Fl m Ar variable Ns Op = Ns Ar value
@ -68,9 +69,11 @@ Use
.Ar file
as configuration file instead of the standard one.
.It Fl D Ar options
Debugging options are specified as a comma separated string.
Debugging options are specified with a
.Fl o
flag followed by a comma separated string of options.
The following options are available.
.Bl -tag -width "trace=level"
.Bl -tag -width ".It Cm trace Ns Cm = Ns Cm level"
.It Cm dump
Dump all sent and received PDUs to the terminal.
.It Cm events
@ -80,8 +83,11 @@ to 10.
.It Cm trace Ns Cm = Ns Cm level
Set the snmp library trace flag to the specified
value.
The value can be specified in the usual C-syntax for numbers.
.El
The value can be specified in the usual C-syntax for numbers.
.It Fl e Ar file
Specify an alternate file where the agent's engine id and number of boots
are saved.
.It Fl I Ar paths
Specify a colon separated list of directories to search for configuration
include files.
@ -246,6 +252,8 @@ Default configuration file, where the default
.Aq prefix
is
.Dq snmpd .
.It Pa /var/ Ns Ao Ar prefix Ac Ns \&.engine
Default engine id file.
.It Pa /var/run/ Ns Ao Ar prefix Ac Ns \&.pid
Default pid file.
.It Pa /etc:/usr/etc/:/usr/local/etc

View File

@ -31,6 +31,7 @@
* Parse configuration file.
*/
#include <sys/types.h>
#include <sys/queue.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
@ -810,6 +811,7 @@ parse_oid(const char *varname, struct asn_oid *oid)
struct snmp_node *node;
u_int i;
u_char ip[4];
struct asn_oid str_oid;
for (node = tree; node < &tree[tree_size]; node++)
if (strcmp(varname, node->name) == 0)
@ -824,7 +826,19 @@ parse_oid(const char *varname, struct asn_oid *oid)
report("subid too large %#"QUADXFMT, numval);
if (oid->len == ASN_MAXOIDLEN)
report("index too long");
oid->subs[oid->len++] = numval;
if (gettoken() != ':')
oid->subs[oid->len++] = numval;
else {
str_oid.len = 0;
str_oid.subs[str_oid.len++] = numval;
while (gettoken() == TOK_NUM) {
str_oid.subs[str_oid.len++] = numval;
if (gettoken() != ':')
break;
}
oid->subs[oid->len++] = str_oid.len;
asn_append_oid(oid, &str_oid);
}
} else if (token == TOK_STR) {
if (strvallen + oid->len + 1 > ASN_MAXOIDLEN)
@ -832,6 +846,7 @@ parse_oid(const char *varname, struct asn_oid *oid)
oid->subs[oid->len++] = strvallen;
for (i = 0; i < strvallen; i++)
oid->subs[oid->len++] = strval[i];
gettoken();
} else if (token == TOK_HOST) {
gethost(strval, ip);
@ -839,10 +854,9 @@ parse_oid(const char *varname, struct asn_oid *oid)
report("index too long");
for (i = 0; i < 4; i++)
oid->subs[oid->len++] = ip[i];
gettoken();
} else
report("bad token in index");
gettoken();
}
return (node);
@ -1006,7 +1020,7 @@ parse_assign(const char *varname)
node = parse_oid(varname, &vindex);
if (token != '=')
report("'=' expected");
report("'=' expected, got '%c'", token);
gettoken();
if (ignore) {

View File

@ -31,6 +31,7 @@
* Support functions for modules.
*/
#include <sys/types.h>
#include <sys/queue.h>
#include <sys/un.h>
#include <stdio.h>
#include <stdlib.h>

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@
*
* Private SNMPd data and functions.
*/
#include <sys/queue.h>
#ifdef USE_LIBBEGEMOT
#include <rpoll.h>
#else
@ -247,7 +247,8 @@ extern struct snmpd snmpd;
#define VERS_ENABLE_V1 0x00000001
#define VERS_ENABLE_V2C 0x00000002
#define VERS_ENABLE_ALL 0x00000003
#define VERS_ENABLE_V3 0x00000004
#define VERS_ENABLE_ALL (VERS_ENABLE_V1 | VERS_ENABLE_V2C | VERS_ENABLE_V3)
/*
* The debug group
@ -279,6 +280,11 @@ struct snmpd_stats {
};
extern struct snmpd_stats snmpd_stats;
/*
* SNMPd Engine
*/
extern struct snmp_engine snmpd_engine;
/*
* OR Table
*/
@ -322,6 +328,11 @@ extern const char *syspath;
extern int32_t snmp_serial_no;
int init_actvals(void);
extern char engine_file[];
int init_snmpd_engine(void);
int set_snmpd_engine(void);
int read_config(const char *, struct lmodule *);
int define_macro(const char *name, const char *value);

View File

@ -31,7 +31,7 @@
.\"
.\" $Begemot: bsnmp/snmpd/snmpmod.3,v 1.14 2005/10/04 13:30:35 brandt_h Exp $
.\"
.Dd February 27, 2006
.Dd September 9, 2010
.Dt SNMPMOD 3
.Os
.Sh NAME
@ -60,6 +60,8 @@
.Nm comm_define ,
.Nm community ,
.Nm oid_zeroDotZero ,
.Nm oid_usmUnknownEngineIDs ,
.Nm oid_usmNotInTimeWindows ,
.Nm reqid_allocate ,
.Nm reqid_next ,
.Nm reqid_base ,
@ -99,7 +101,16 @@
.Nm index_compare ,
.Nm index_compare_off ,
.Nm index_append ,
.Nm index_append_off
.Nm index_append_off,
.Nm bsnmpd_get_usm_stats,
.Nm bsnmpd_reset_usm_stats,
.Nm usm_first_user,
.Nm usm_next_user,
.Nm usm_find_user,
.Nm usm_new_user,
.Nm usm_delete_user,
.Nm usm_flush_users,
.Nm usm_user
.Nd "SNMP daemon loadable module interface"
.Sh LIBRARY
Begemot SNMP library
@ -228,6 +239,25 @@ Begemot SNMP library
.Fn index_append "struct asn_oid *dst" "u_int sub" "const struct asn_oid *src"
.Ft void
.Fn index_append_off "struct asn_oid *dst" "u_int sub" "const struct asn_oid *src" "u_int off"
.Ft struct snmpd_usmstat *
.Fn bsnmpd_get_usm_stats "void"
.Ft void
.Fn bsnmpd_reset_usm_stats "void"
.Ft struct usm_user *
.Fn usm_first_user "void"
.Ft struct usm_user *
.Fn usm_next_user "struct usm_user *uuser"
.Ft struct usm_user *
.Fn usm_find_user "uint8_t *engine" "uint32_t elen" "char *uname"
.Ft struct usm_user *
.Fn usm_new_user "uint8_t *engine" "uint32_t elen" "char *uname"
.Ft void
.Fn usm_delete_user "struct usm_user *"
.Ft void
.Fn usm_flush_users "void"
.Vt extern struct usm_user *usm_user;
.Vt extern const struct asn_oid oid_usmUnknownEngineIDs;
.Vt extern const struct asn_oid oid_usmNotInTimeWindows;
.Sh DESCRIPTION
The
.Xr bsnmpd 1
@ -539,7 +569,7 @@ This is the initial community string.
.El
.Pp
The function returns a globally unique community identifier.
If a PDU is
If a SNMPv1 or SNMPv2 PDU is
received who's community string matches, this identifier is set into the global
.Va community .
.Pp
@ -549,10 +579,76 @@ returns the current community string for the given community.
.Pp
All communities defined by a module are automatically released when the module
is unloaded.
.Ss THE USER-BASED SECURITY GROUP
The scalar statistics of the USM group are held in the global variable
.Va snmpd_usmstats :
.Bd -literal -offset indent
struct snmpd_usmstat {
uint32_t unsupported_seclevels;
uint32_t not_in_time_windows;
uint32_t unknown_users;
uint32_t unknown_engine_ids;
uint32_t wrong_digests;
uint32_t decrypt_errors;
};
.Ed
.Fn bsnmpd_get_usm_stats
returns a pointer to the global structure containing the statistics.
.Fn bsnmpd_reset_usm_stats
clears the statistics of the USM group.
.Pp
A global list of configured USM users is maintained by the daemon.
.Bd -literal -offset indent
struct usm_user {
struct snmp_user suser;
uint8_t user_engine_id[SNMP_ENGINE_ID_SIZ];
uint32_t user_engine_len;
char user_public[SNMP_USM_NAME_SIZ];
uint32_t user_public_len;
int32_t status;
int32_t type;
SLIST_ENTRY(usm_user) up;
};
.Ed
This structure represents an USM user. The daemon only responds to SNMPv3 PDUs
with user credentials matching an USM user entry in its global list.
If a SNMPv3 PDU is received, whose security model is USM, the global
.Va usm_user
is set to point at the user entry that matches the credentials contained in
the PDU.
However, the daemon does not create or remove USM users, it gives an interface
to external loadable module(s) to manage the list.
.Fn usm_new_user
adds an user entry in the list, and
.Fn usm_delete_user
deletes an existing entry from the list.
.Fn usm_flush_users
is used to remove all configured USM users.
.Fn usm_first_user
will return the first user in the list, or
.Li NULL
if the list is empty.
.Fn usm_next_user
will return the next user of a given entry if one exists, or
.Li NULL .
The list is sorted according to the USM user name and Engine ID.
.Fn usm_find_user
returns the USM user entry matching the given
.Fa engine
and
.Fa uname
or
.Li NULL
if an user with the specified name and engine id is not present in the list.
.Ss WELL KNOWN OIDS
The global variable
.Va oid_zeroDotZero
contains the OID 0.0.
The global variables
.Va oid_usmUnknownEngineIDs
.Va oid_usmNotInTimeWindows
contains the OIDs 1.3.6.1.6.3.15.1.1.4.0 and 1.3.6.1.6.3.15.1.1.2.0 used
in the SNMPv3 USM Engine Discovery.
.Ss REQUEST ID RANGES
For modules that implement SNMP client functions besides SNMP agent functions
it may be necessary to identify SNMP requests by their identifier to allow

View File

@ -332,11 +332,137 @@ const char * comm_string(u_int);
/* community for current packet */
extern u_int community;
/*
/*
* SNMP User-based Security Model data. Modified via the snmp_usm(3) module.
*/
struct snmpd_usmstat {
uint32_t unsupported_seclevels;
uint32_t not_in_time_windows;
uint32_t unknown_users;
uint32_t unknown_engine_ids;
uint32_t wrong_digests;
uint32_t decrypt_errors;
};
extern struct snmpd_usmstat snmpd_usmstats;
struct snmpd_usmstat *bsnmpd_get_usm_stats(void);
void bsnmpd_reset_usm_stats(void);
struct usm_user {
struct snmp_user suser;
uint8_t user_engine_id[SNMP_ENGINE_ID_SIZ];
uint32_t user_engine_len;
char user_public[SNMP_ADM_STR32_SIZ];
uint32_t user_public_len;
int32_t status;
int32_t type;
SLIST_ENTRY(usm_user) up;
};
SLIST_HEAD(usm_userlist, usm_user);
struct usm_user *usm_first_user(void);
struct usm_user *usm_next_user(struct usm_user *);
struct usm_user *usm_find_user(uint8_t *, uint32_t, char *);
struct usm_user *usm_new_user(uint8_t *, uint32_t, char *);
void usm_delete_user(struct usm_user *);
void usm_flush_users(void);
/* USM user for current packet */
extern struct usm_user *usm_user;
/*
* SNMP View-based Access Control Model data. Modified via the snmp_vacm(3) module.
*/
struct vacm_group;
struct vacm_user {
/* Security user name from USM */
char secname[SNMP_ADM_STR32_SIZ];
int32_t sec_model;
/* Back pointer to user assigned group name */
struct vacm_group *group;
int32_t type;
int32_t status;
SLIST_ENTRY(vacm_user) vvu;
SLIST_ENTRY(vacm_user) vvg;
};
SLIST_HEAD(vacm_userlist, vacm_user);
struct vacm_group {
char groupname[SNMP_ADM_STR32_SIZ];
struct vacm_userlist group_users;
SLIST_ENTRY(vacm_group) vge;
};
SLIST_HEAD(vacm_grouplist, vacm_group);
struct vacm_access {
/* The group name is index, not a column in the table */
struct vacm_group *group;
char ctx_prefix[SNMP_ADM_STR32_SIZ];
int32_t sec_model;
int32_t sec_level;
int32_t ctx_match;
struct vacm_view *read_view;
struct vacm_view *write_view;
struct vacm_view *notify_view;
int32_t type;
int32_t status;
TAILQ_ENTRY(vacm_access) vva;
};
TAILQ_HEAD(vacm_accesslist, vacm_access);
struct vacm_view {
char viewname[SNMP_ADM_STR32_SIZ]; /* key */
struct asn_oid subtree; /* key */
uint8_t mask[16];
uint8_t exclude;
int32_t type;
int32_t status;
SLIST_ENTRY(vacm_view) vvl;
};
SLIST_HEAD(vacm_viewlist, vacm_view);
struct vacm_context {
/* The ID of the module that registered this context */
int32_t regid;
char ctxname[SNMP_ADM_STR32_SIZ];
SLIST_ENTRY(vacm_context) vcl;
};
SLIST_HEAD(vacm_contextlist, vacm_context);
void vacm_groups_init(void);
struct vacm_user *vacm_first_user(void);
struct vacm_user *vacm_next_user(struct vacm_user *);
struct vacm_user *vacm_new_user(int32_t, char *);
int vacm_delete_user(struct vacm_user *);
int vacm_user_set_group(struct vacm_user *, u_char *, u_int);
struct vacm_access *vacm_first_access_rule(void);
struct vacm_access *vacm_next_access_rule(struct vacm_access *);
struct vacm_access *vacm_new_access_rule(char *, char *, int32_t, int32_t);
int vacm_delete_access_rule(struct vacm_access *);
struct vacm_view *vacm_first_view(void);
struct vacm_view *vacm_next_view(struct vacm_view *);
struct vacm_view *vacm_new_view(char *, struct asn_oid *);
int vacm_delete_view(struct vacm_view *);
struct vacm_context *vacm_first_context(void);
struct vacm_context *vacm_next_context(struct vacm_context *);
struct vacm_context *vacm_add_context(char *, int32_t);
void vacm_flush_contexts(int32_t);
/*
* Well known OIDs
*/
extern const struct asn_oid oid_zeroDotZero;
/* SNMPv3 Engine Discovery */
extern const struct asn_oid oid_usmUnknownEngineIDs;
extern const struct asn_oid oid_usmNotInTimeWindows;
/*
* Request ID ranges.
*

View File

@ -31,6 +31,7 @@
* Local domain socket transport
*/
#include <sys/types.h>
#include <sys/queue.h>
#include <sys/un.h>
#include <sys/stat.h>

View File

@ -31,6 +31,7 @@
* UDP transport
*/
#include <sys/types.h>
#include <sys/queue.h>
#include <stdlib.h>
#include <syslog.h>

View File

@ -31,6 +31,7 @@
* TrapSinkTable
*/
#include <sys/types.h>
#include <sys/queue.h>
#include <sys/sysctl.h>
#include <sys/un.h>
#include <stdio.h>

View File

@ -196,5 +196,15 @@
)
)
)
(10 snmpFrameworkMIB
(2 snmpFrameworkMIBObjects
(1 snmpEngine
(1 snmpEngineID OCTETSTRING | SnmpEngineID op_snmp_engine GET)
(2 snmpEngineBoots INTEGER op_snmp_engine GET)
(3 snmpEngineTime INTEGER op_snmp_engine GET)
(4 snmpEngineMaxMessageSize INTEGER op_snmp_engine GET)
)
)
)
))
)

View File

@ -56,13 +56,14 @@ struct aslookup {
};
void *
as_setup(char *server)
as_setup(const char *server)
{
struct aslookup *asn;
struct addrinfo hints, *res0, *res;
FILE *f;
int s, error;
s = -1;
if (server == NULL)
server = getenv("RA_SERVER");
if (server == NULL)

View File

@ -30,6 +30,6 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
void *as_setup(char *);
void *as_setup(const char *);
unsigned int as_lookup(void *, char *, sa_family_t);
void as_shutdown(void *);

View File

@ -71,14 +71,14 @@ ifaddrlist(register struct ifaddrlist **ipaddrp, register char *errbuf)
{
register int fd, nipaddr;
#ifdef HAVE_SOCKADDR_SA_LEN
register int n;
size_t n;
#endif
register struct ifreq *ifrp, *ifend, *ifnext, *mp;
register struct sockaddr_in *sin;
register struct ifaddrlist *al;
struct ifconf ifc;
struct ifreq ibuf[(32 * 1024) / sizeof(struct ifreq)], ifr;
#define MAX_IPADDR (sizeof(ibuf) / sizeof(ibuf[0]))
#define MAX_IPADDR ((int)(sizeof(ibuf) / sizeof(ibuf[0])))
static struct ifaddrlist ifaddrlist[MAX_IPADDR];
char device[sizeof(ifr.ifr_name) + 1];
@ -91,10 +91,10 @@ ifaddrlist(register struct ifaddrlist **ipaddrp, register char *errbuf)
ifc.ifc_buf = (caddr_t)ibuf;
if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0 ||
ifc.ifc_len < sizeof(struct ifreq)) {
ifc.ifc_len < (int)sizeof(struct ifreq)) {
if (errno == EINVAL)
(void)sprintf(errbuf,
"SIOCGIFCONF: ifreq struct too small (%d bytes)",
"SIOCGIFCONF: ifreq struct too small (%zu bytes)",
sizeof(ibuf));
else
(void)sprintf(errbuf, "SIOCGIFCONF: %s",

View File

@ -220,7 +220,6 @@ static const char rcsid[] =
#include <netinet/ip_var.h>
#include <netinet/ip_icmp.h>
#include <netinet/udp.h>
#include <netinet/udp_var.h>
#include <netinet/tcp.h>
#include <netinet/tcpip.h>
@ -1424,7 +1423,7 @@ tcp_check(const u_char *data, int seq)
return (ntohs(tcp->th_sport) == ident
&& ntohs(tcp->th_dport) == port + (fixedPort ? 0 : seq))
&& tcp->th_seq == (ident << 16) | (port + seq);
&& tcp->th_seq == (((tcp_seq)ident << 16) | (port + seq));
}
void
@ -1497,19 +1496,17 @@ u_short
p_cksum(struct ip *ip, u_short *data, int len)
{
static struct ipovly ipo;
u_short sumh, sumd;
u_long sumt;
u_short sum[2];
ipo.ih_pr = ip->ip_p;
ipo.ih_len = htons(len);
ipo.ih_src = ip->ip_src;
ipo.ih_dst = ip->ip_dst;
sumh = in_cksum((u_short*)&ipo, sizeof(ipo)); /* pseudo ip hdr cksum */
sumd = in_cksum((u_short*)data, len); /* payload data cksum */
sumt = (sumh << 16) | (sumd);
sum[1] = in_cksum((u_short*)&ipo, sizeof(ipo)); /* pseudo ip hdr cksum */
sum[0] = in_cksum(data, len); /* payload data cksum */
return ~in_cksum((u_short*)&sumt, sizeof(sumt));
return ~in_cksum(sum, sizeof(sum));
}
/*

View File

@ -0,0 +1,25 @@
The OpenSSL project depends on volunteer efforts and financial support from
the end user community. That support comes in the form of donations and paid
sponsorships, software support contracts, paid consulting services
and commissioned software development.
Since all these activities support the continued development and improvement
of OpenSSL we consider all these clients and customers as sponsors of the
OpenSSL project.
We would like to identify and thank the following such sponsors for their past
or current significant support of the OpenSSL project:
Very significant support:
OpenGear: www.opengear.com
Significant support:
PSW Group: www.psw.net
Please note that we ask permission to identify sponsors and that some sponsors
we consider eligible for inclusion here have requested to remain anonymous.
Additional sponsorship or financial support is always welcome: for more
information please contact the OpenSSL Software Foundation.

View File

@ -2,6 +2,18 @@
OpenSSL CHANGES
_______________
Changes between 0.9.8p and 0.9.8q [2 Dec 2010]
*) Disable code workaround for ancient and obsolete Netscape browsers
and servers: an attacker can use it in a ciphersuite downgrade attack.
Thanks to Martin Rex for discovering this bug. CVE-2010-4180
[Steve Henson]
*) Fixed J-PAKE implementation error, originally discovered by
Sebastien Martini, further info and confirmation from Stefan
Arentz and Feng Hao. Note that this fix is a security fix. CVE-2010-4252
[Ben Laurie]
Changes between 0.9.8o and 0.9.8p [16 Nov 2010]
*) Fix extension code to avoid race conditions which can result in a buffer

View File

@ -52,6 +52,9 @@ OpenSSL - Frequently Asked Questions
* Why does the OpenSSL test suite fail in sha512t on x86 CPU?
* Why does compiler fail to compile sha512.c?
* Test suite still fails, what to do?
* I think I've found a bug, what should I do?
* I'm SURE I've found a bug, how do I report it?
* I've found a security issue, how do I report it?
[PROG] Questions about programming with OpenSSL
@ -79,7 +82,7 @@ OpenSSL - Frequently Asked Questions
* Which is the current version of OpenSSL?
The current version is available from <URL: http://www.openssl.org>.
OpenSSL 1.0.0b was released on Nov 16th, 2010.
OpenSSL 1.0.0c was released on Dec 2nd, 2010.
In addition to the current stable release, you can also access daily
snapshots of the OpenSSL development version at <URL:
@ -131,7 +134,7 @@ OpenSSL. Information on the OpenSSL mailing lists is available from
* Where can I get a compiled version of OpenSSL?
You can finder pointers to binary distributions in
http://www.openssl.org/related/binaries.html .
<URL: http://www.openssl.org/related/binaries.html> .
Some applications that use OpenSSL are distributed in binary form.
When using such an application, you don't need to install OpenSSL
@ -463,7 +466,7 @@ administrators.
Other projects do have other policies so you can for example extract the CA
bundle used by Mozilla and/or modssl as described in this article:
http://www.mail-archive.com/modssl-users@modssl.org/msg16980.html
<URL: http://www.mail-archive.com/modssl-users@modssl.org/msg16980.html>
[BUILD] =======================================================================
@ -505,7 +508,7 @@ when you run the test suite (using "make test"). The message returned is
"bc: 1 not implemented".
The best way to deal with this is to find another implementation of bc
and compile/install it. GNU bc (see http://www.gnu.org/software/software.html
and compile/install it. GNU bc (see <URL: http://www.gnu.org/software/software.html>
for download instructions) can be safely used, for example.
@ -516,7 +519,7 @@ that the OpenSSL bntest throws at it. This gets triggered when you run the
test suite (using "make test"). The message returned is "bc: stack empty".
The best way to deal with this is to find another implementation of bc
and compile/install it. GNU bc (see http://www.gnu.org/software/software.html
and compile/install it. GNU bc (see <URL: http://www.gnu.org/software/software.html>
for download instructions) can be safely used, for example.
@ -709,6 +712,46 @@ never make sense, and tend to emerge when you least expect them. In order
to identify one, drop optimization level, e.g. by editing CFLAG line in
top-level Makefile, recompile and re-run the test.
* I think I've found a bug, what should I do?
If you are a new user then it is quite likely you haven't found a bug and
something is happening you aren't familiar with. Check this FAQ, the associated
documentation and the mailing lists for similar queries. If you are still
unsure whether it is a bug or not submit a query to the openssl-users mailing
list.
* I'm SURE I've found a bug, how do I report it?
Bug reports with no security implications should be sent to the request
tracker. This can be done by mailing the report to <rt@openssl.org> (or its
alias <openssl-bugs@openssl.org>), please note that messages sent to the
request tracker also appear in the public openssl-dev mailing list.
The report should be in plain text. Any patches should be sent as
plain text attachments because some mailers corrupt patches sent inline.
If your issue affects multiple versions of OpenSSL check any patches apply
cleanly and, if possible include patches to each affected version.
The report should be given a meaningful subject line briefly summarising the
issue. Just "bug in OpenSSL" or "bug in OpenSSL 0.9.8n" is not very helpful.
By sending reports to the request tracker the bug can then be given a priority
and assigned to the appropriate maintainer. The history of discussions can be
accessed and if the issue has been addressed or a reason why not. If patches
are only sent to openssl-dev they can be mislaid if a team member has to
wade through months of old messages to review the discussion.
See also <URL: http://www.openssl.org/support/rt.html>
* I've found a security issue, how do I report it?
If you think your bug has security implications then please send it to
openssl-security@openssl.org if you don't get a prompt reply at least
acknowledging receipt then resend or mail it directly to one of the
more active team members (e.g. Steve).
[PROG] ========================================================================
* Is OpenSSL thread-safe?

View File

@ -4,7 +4,7 @@
## Makefile for OpenSSL
##
VERSION=0.9.8p
VERSION=0.9.8q
MAJOR=0
MINOR=9.8
SHLIB_VERSION_NUMBER=0.9.8

View File

@ -5,6 +5,11 @@
This file gives a brief overview of the major changes between each OpenSSL
release. For more details please read the CHANGES file.
Major changes between OpenSSL 0.9.8p and OpenSSL 0.9.8q:
o Fix for security issue CVE-2010-4180
o Fix for CVE-2010-4252
Major changes between OpenSSL 0.9.8o and OpenSSL 0.9.8p:
o Fix for security issue CVE-2010-3864.

View File

@ -1,5 +1,5 @@
OpenSSL 0.9.8p 16 Nov 2010
OpenSSL 0.9.8q 2 Dec 2010
Copyright (c) 1998-2009 The OpenSSL Project
Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson

View File

@ -81,7 +81,7 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen,
unsigned char m[EVP_MAX_MD_SIZE];
unsigned int m_len;
int i,ok=0,v;
MS_STATIC EVP_MD_CTX tmp_ctx;
EVP_MD_CTX tmp_ctx;
*siglen=0;
for (i=0; i<4; i++)

View File

@ -68,7 +68,7 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
unsigned char m[EVP_MAX_MD_SIZE];
unsigned int m_len;
int i,ok=0,v;
MS_STATIC EVP_MD_CTX tmp_ctx;
EVP_MD_CTX tmp_ctx;
for (i=0; i<4; i++)
{

View File

@ -283,23 +283,53 @@ int JPAKE_STEP1_generate(JPAKE_STEP1 *send, JPAKE_CTX *ctx)
return 1;
}
/* g^x is a legal value */
static int is_legal(const BIGNUM *gx, const JPAKE_CTX *ctx)
{
BIGNUM *t;
int res;
if(BN_is_negative(gx) || BN_is_zero(gx) || BN_cmp(gx, ctx->p.p) >= 0)
return 0;
t = BN_new();
BN_mod_exp(t, gx, ctx->p.q, ctx->p.p, ctx->ctx);
res = BN_is_one(t);
BN_free(t);
return res;
}
int JPAKE_STEP1_process(JPAKE_CTX *ctx, const JPAKE_STEP1 *received)
{
/* verify their ZKP(xc) */
if(!is_legal(received->p1.gx, ctx))
{
JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_G_TO_THE_X3_IS_NOT_LEGAL);
return 0;
}
if(!is_legal(received->p2.gx, ctx))
{
JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_G_TO_THE_X4_IS_NOT_LEGAL);
return 0;
}
/* verify their ZKP(xc) */
if(!verify_zkp(&received->p1, ctx->p.g, ctx))
{
JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_VERIFY_X3_FAILED);
return 0;
}
/* verify their ZKP(xd) */
/* verify their ZKP(xd) */
if(!verify_zkp(&received->p2, ctx->p.g, ctx))
{
JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_VERIFY_X4_FAILED);
return 0;
}
/* g^xd != 1 */
/* g^xd != 1 */
if(BN_is_one(received->p2.gx))
{
JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_G_TO_THE_X4_IS_ONE);

View File

@ -115,6 +115,8 @@ void ERR_load_JPAKE_strings(void);
#define JPAKE_F_VERIFY_ZKP 100
/* Reason codes. */
#define JPAKE_R_G_TO_THE_X3_IS_NOT_LEGAL 108
#define JPAKE_R_G_TO_THE_X4_IS_NOT_LEGAL 109
#define JPAKE_R_G_TO_THE_X4_IS_ONE 105
#define JPAKE_R_HASH_OF_HASH_OF_KEY_MISMATCH 106
#define JPAKE_R_HASH_OF_KEY_MISMATCH 107

View File

@ -1,6 +1,6 @@
/* crypto/jpake/jpake_err.c */
/* ====================================================================
* Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved.
* Copyright (c) 1999-2010 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -80,6 +80,8 @@ static ERR_STRING_DATA JPAKE_str_functs[]=
static ERR_STRING_DATA JPAKE_str_reasons[]=
{
{ERR_REASON(JPAKE_R_G_TO_THE_X3_IS_NOT_LEGAL),"g to the x3 is not legal"},
{ERR_REASON(JPAKE_R_G_TO_THE_X4_IS_NOT_LEGAL),"g to the x4 is not legal"},
{ERR_REASON(JPAKE_R_G_TO_THE_X4_IS_ONE) ,"g to the x4 is one"},
{ERR_REASON(JPAKE_R_HASH_OF_HASH_OF_KEY_MISMATCH),"hash of hash of key mismatch"},
{ERR_REASON(JPAKE_R_HASH_OF_KEY_MISMATCH),"hash of key mismatch"},

View File

@ -25,11 +25,11 @@
* (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
* major minor fix final patch/beta)
*/
#define OPENSSL_VERSION_NUMBER 0x0090810f
#define OPENSSL_VERSION_NUMBER 0x0090811f
#ifdef OPENSSL_FIPS
#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8p-fips 16 Nov 2010"
#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8q-fips 2 Dec 2010"
#else
#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8p 16 Nov 2010"
#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.8q 2 Dec 2010"
#endif
#define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT

View File

@ -127,7 +127,7 @@ STACK_OF(type) \
sk_is_sorted(CHECKED_PTR_OF(STACK_OF(type), st))
#define SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
(STACK_OF(type) *)d2i_ASN1_SET(CHECKED_PTR_OF(STACK_OF(type), st), \
(STACK_OF(type) *)d2i_ASN1_SET(CHECKED_PTR_OF(STACK_OF(type)*, st), \
pp, length, \
CHECKED_D2I_OF(type, d2i_func), \
CHECKED_SK_FREE_FUNC(type, free_func), \

View File

@ -78,18 +78,7 @@ this breaks this server so 16 bytes is the way to go.
=item SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
ssl3.netscape.com:443, first a connection is established with RC4-MD5.
If it is then resumed, we end up using DES-CBC3-SHA. It should be
RC4-MD5 according to 7.6.1.3, 'cipher_suite'.
Netscape-Enterprise/2.01 (https://merchant.netscape.com) has this bug.
It only really shows up when connecting via SSLv2/v3 then reconnecting
via SSLv3. The cipher list changes....
NEW INFORMATION. Try connecting with a cipher list of just
DES-CBC-SHA:RC4-MD5. For some weird reason, each new connection uses
RC4-MD5, but a re-connect tries to use DES-CBC-SHA. So netscape, when
doing a re-connect, always takes the first cipher in the cipher list.
As of OpenSSL 0.9.8q and 1.0.0c, this option has no effect.
=item SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG

View File

@ -2,7 +2,7 @@
%define libmaj 0
%define libmin 9
%define librel 8
%define librev p
%define librev q
Release: 1
%define openssldir /var/ssl

View File

@ -814,8 +814,11 @@ int ssl3_get_server_hello(SSL *s)
s->session->cipher_id = s->session->cipher->id;
if (s->hit && (s->session->cipher_id != c->id))
{
/* Workaround is now obsolete */
#if 0
if (!(s->options &
SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG))
#endif
{
al=SSL_AD_ILLEGAL_PARAMETER;
SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED);

View File

@ -927,6 +927,10 @@ int ssl3_get_client_hello(SSL *s)
break;
}
}
/* Disabled because it can be used in a ciphersuite downgrade
* attack: CVE-2010-4180.
*/
#if 0
if (j == 0 && (s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG) && (sk_SSL_CIPHER_num(ciphers) == 1))
{
/* Special case as client bug workaround: the previously used cipher may
@ -941,6 +945,7 @@ int ssl3_get_client_hello(SSL *s)
j = 1;
}
}
#endif
if (j == 0)
{
/* we need to have the cipher in the cipher

View File

@ -12,6 +12,15 @@ system := 1 # FreeBSD
traphost := localhost
trapport := 162
#
# Set the SNMP engine ID.
#
# The snmpEngineID object required from the SNMPv3 Framework. If not explicitly set via
# this configuration file, an ID is assigned based on the value of the
# kern.hostid variable
# engine := 0x80:0x10:0x08:0x10:0x80:0x25
# snmpEngineID = $(engine)
# Change this!
read := "public"
# Uncomment begemotSnmpdCommunityString.0.2 below that sets the community
@ -19,6 +28,26 @@ read := "public"
write := "geheim"
trap := "mytrap"
# Declarations for SNMP-USER-BASED-SM-MIB authentication and privacy options
NoAuthProtocol := 1.3.6.1.6.3.10.1.1.1
HMACMD5AuthProtocol := 1.3.6.1.6.3.10.1.1.2
HMACSHAAuthProtocol := 1.3.6.1.6.3.10.1.1.3
NoPrivProtocol := 1.3.6.1.6.3.10.1.2.1
DESPrivProtocol := 1.3.6.1.6.3.10.1.2.2
AesCfb128Protocol := 1.3.6.1.6.3.10.1.2.4
#
# SNMPv3 USM User definition
#
# The localized hex password for a user may be obtained by setting SNMPUSER, SNMPPASSWD,
# SNMPAUTH and SNMPPRIV environment variables to the desired parameters and invoking
# 'bsnmpget -v 3 -D -K -o verbose' against the running bsnmpd(1). For other
# usages refer to the bsnmpget(1) manual page. The following lines define a user "bsnmp"
# with a private password "bsnmp", localized for the above engine ID.
#
# user1 := "bsnmp"
# user1passwd := 0x1b:0x6d:0x9e:0x94:0xbe:0x19:0x17:0xfb:0xde:0x60:0x46:0xfe:0x59:0x6f:0x61:0x95:0xf2:0xc9:0x57:0x1f
#
# Configuration
#
@ -72,6 +101,113 @@ begemotSnmpdModulePath."mibII" = "/usr/lib/snmp_mibII.so"
#begemotIfForcePoll = 2000
#
# SNMPv3 User-based security module - must be loaded for SNMPv3 USM
#
#begemotSnmpdModulePath."usm" = "/usr/lib/snmp_usm.so"
#
# SNMPv3 USM User definition.
#
#%usm
#
# The following block creates a user with name "bsnmp" and sets privacy
# and encryption options to SHA256 message digests and AES encryption
# for this user.
#
# usmUserStatus.$(engine).$(user1) = 5
# usmUserAuthProtocol.$(engine).$(user1) = $(HMACSHAAuthProtocol)
# usmUserAuthKeyChange.$(engine).$(user1) = $(user1passwd)
# usmUserPrivProtocol.$(engine).$(user1) = $(AesCfb128Protocol)
# usmUserPrivKeyChange.$(engine).$(user1) = $(user1passwd)
# usmUserStatus.$(engine).$(user1) = 1
#
#
# The following block creates a user with name "public" with no authentication
# or encryption options.
#
# usmUserStatus.$(engine).$(read) = 5
# usmUserAuthProtocol.$(engine).$(read) = $(NoAuthProtocol)
# usmUserPrivProtocol.$(engine).$(read) = $(NoPrivProtocol)
# usmUserStatus.$(engine).$(read) = 1
#
#
# SNMPv3 View-based Access Control module
#
#begemotSnmpdModulePath."vacm" = "/usr/lib/snmp_vacm.so"
#
# Definition of view-based access control entries.
#
#%vacm
# Definition of a SNMPv1 group
# vacmSecurityToGroupStatus.1.$(read) = 4
# vacmGroupName.1.$(read) = $(read)
# Definition of SNMPv2 group
# vacmSecurityToGroupStatus.2.$(write) = 4
# vacmGroupName.2.$(write) = $(write)
# Definition of SNMPv3 group with users "bsnmp" and "public"
# vacmSecurityToGroupStatus.3.$(user1) = 4
# vacmGroupName.3.$(user1) = $(write)
# vacmSecurityToGroupStatus.3.$(read) = 4
# vacmGroupName.3.$(read) = $(write)
#
# The OID of the .iso.org.dod.internet subtree
#
# internetoid := 1.3.6.1
# internetoidlen := 4
# Enumerated values for the privacy options
# noAuthNoPriv := 1
# authNoPriv := 2
# authPriv := 3
#
# Definitions of two views
#
# vacmViewTreeFamilyStatus."internet".$(internetoidlen).$(internetoid) = 4
# vacmViewTreeFamilyStatus."restricted".$(internetoidlen).$(internetoid) = 4
#
# Access control
#
#
# Read-only access for SNMPv1 users
#
# vacmAccessStatus.$(read)."".1.1 = 4
# vacmAccessReadViewName.$(read)."".1.1 = "internet"
#
# Read-write access for SNMPv2 users
#
# vacmAccessStatus.$(write)."".2.1 = 4
# vacmAccessReadViewName.$(write)."".2.1 = "internet"
# vacmAccessWriteViewName.$(write)."".2.1 = "internet"
#
# Read-write-notify access for SNMPv3 USM users with noAuthNoPriv
#
# vacmAccessStatus.$(write)."".3.$(noAuthNoPriv) = 4
# vacmAccessReadViewName.$(write)."".3.$(noAuthNoPriv) = "internet"
# vacmAccessWriteViewName.$(write)."".3.$(noAuthNoPriv) = "internet"
# vacmAccessNotifyViewName.$(write)."".3.$(noAuthNoPriv) = "internet"
#
#Read-write-notify access to restricted for SNMPv3 USM users with authPriv
#
# vacmAccessStatus.$(write)."".3.$(authPriv) = 4
# vacmAccessReadViewName.$(write)."".3.$(authPriv) = "restricted"
# vacmAccessWriteViewName.$(write)."".3.$(authPriv) = "restricted"
# vacmAccessNotifyViewName.$(write)."".3.$(authPriv) = "restricted"
# Netgraph module
#
#begemotSnmpdModulePath."netgraph" = "/usr/lib/snmp_netgraph.so"

View File

@ -9,11 +9,7 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"

View File

@ -9,11 +9,7 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"

View File

@ -11,11 +11,7 @@
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# 3. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
@ -32,6 +28,6 @@
# SUCH DAMAGE.
#
# @(#)rot13.sh 8.1 (Berkeley) 5/31/93
#
# $FreeBSD$
exec /usr/games/caesar 13 "$@"

View File

@ -12,11 +12,7 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"

View File

@ -10,11 +10,7 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"

View File

@ -9,11 +9,7 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"

View File

@ -9,11 +9,7 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"

View File

@ -9,11 +9,7 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgment:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"

View File

@ -24,6 +24,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#ifndef lint
#ifndef __GNUC__
#error "GCC is needed to compile this file"
@ -92,5 +95,3 @@ __asm__("eprol:");
_init();
exit( main(argc, argv, env) );
}
__asm__(".ident\t\"$FreeBSD$\"");

View File

@ -23,6 +23,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
.section .init,"ax",@progbits
.align 4
.globl _init
@ -36,6 +39,3 @@ _init:
.type _fini,@function
_fini:
subq $8,%rsp
.section .rodata
.ascii "$FreeBSD$\0"

View File

@ -23,6 +23,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
.section .init,"ax",@progbits
addq $8,%rsp
ret
@ -30,6 +33,3 @@
.section .fini,"ax",@progbits
addq $8,%rsp
ret
.section .rodata
.ascii "$FreeBSD$\0"

View File

@ -39,6 +39,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#ifndef lint
#ifndef __GNUC__
#error "GCC is needed to compile this file"
@ -49,7 +52,6 @@
#include "libc_private.h"
#include "crtbrand.c"
#include <machine/asm.h>
struct Struct_Obj_Entry;
struct ps_strings;
@ -136,5 +138,3 @@ __asm__(".text");
__asm__("eprol:");
__asm__(".previous");
#endif
__asm__(".ident\t\"$FreeBSD$\"");

View File

@ -1,5 +1,6 @@
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
.section .init,"ax",%progbits
ldmea fp, {fp, sp, pc}
mov pc, lr

View File

@ -26,6 +26,9 @@
* $FreeBSD$
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#ifndef lint
#ifndef __GNUC__
#error "GCC is needed to compile this file"

View File

@ -25,6 +25,8 @@
* $FreeBSD$
*/
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
.text
.align 4
@ -47,5 +49,3 @@ _start:
int3
.cfi_endproc
.size _start, . - _start
.ident "$FreeBSD$"

View File

@ -23,6 +23,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
.section .init,"ax",@progbits
.align 4
.globl _init
@ -36,6 +39,3 @@ _init:
.type _fini,@function
_fini:
sub $12,%esp /* re-align stack pointer */
.section .rodata
.ascii "$FreeBSD$\0"

View File

@ -23,6 +23,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
.section .init,"ax",@progbits
add $12,%esp
ret
@ -30,6 +33,3 @@
.section .fini,"ax",@progbits
add $12,%esp
ret
.section .rodata
.ascii "$FreeBSD$\0"

View File

@ -24,7 +24,8 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
.ident "$FreeBSD$"
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
.text

View File

@ -26,6 +26,9 @@
* $FreeBSD$
*/
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
/*
* This file (and its companion crtn.S) form the terminators of the
* .init and .fini sections.

View File

@ -26,6 +26,9 @@
* $FreeBSD$
*/
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
.file "crtn.S"
.section .init,"ax",@progbits

View File

@ -39,6 +39,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#ifndef lint
#ifndef __GNUC__
#error "GCC is needed to compile this file"
@ -120,5 +123,3 @@ __asm__(".text");
__asm__("eprol:");
__asm__(".previous");
#endif
__asm__(".ident\t\"$FreeBSD$\"");

Some files were not shown because too many files have changed in this diff Show More