adding zephyr-im master branch
This commit is contained in:
81
lib/Makefile.in
Normal file
81
lib/Makefile.in
Normal file
@ -0,0 +1,81 @@
|
||||
SHELL=@SHELL@
|
||||
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
datadir=@datadir@
|
||||
sysconfdir=@sysconfdir@
|
||||
sbindir=@sbindir@
|
||||
lsbindir=@lsbindir@
|
||||
datarootdir=@datarootdir@
|
||||
top_builddir=..
|
||||
|
||||
includedir=@includedir@
|
||||
mandir=@mandir@
|
||||
libdir=@libdir@
|
||||
LIBS=@LIBS@
|
||||
|
||||
srcdir=@srcdir@
|
||||
top_srcdir=@top_srcdir@
|
||||
BUILDTOP=..
|
||||
VPATH=@srcdir@
|
||||
LIBTOOL=@LIBTOOL@
|
||||
CC=@CC@
|
||||
INSTALL=@INSTALL@
|
||||
RANLIB=@RANLIB@
|
||||
|
||||
DEBUG=-O
|
||||
CPPFLAGS=@CPPFLAGS@
|
||||
CFLAGS=@CFLAGS@ ${DEBUG}
|
||||
ALL_CFLAGS=${CFLAGS} -DSYSCONFDIR=\"${sysconfdir}\" -I${top_srcdir}/h \
|
||||
-I${BUILDTOP}/h ${CPPFLAGS}
|
||||
LDFLAGS=@LDFLAGS@
|
||||
LIBS=@LIBZEPHYR_LIBS@ -lcom_err @LIBICONV@
|
||||
|
||||
OBJS = zephyr_err.lo ZAsyncLocate.lo ZCkAuth.lo ZCkIfNot.lo ZClosePort.lo \
|
||||
ZCmpUID.lo ZCmpUIDP.lo ZFlsLocs.lo ZFlsSubs.lo ZFmtAuth.lo \
|
||||
ZFmtList.lo ZFmtNotice.lo ZFmtRaw.lo ZFmtRawLst.lo ZFmtSmRLst.lo \
|
||||
ZFmtSmRaw.lo ZFreeNot.lo ZGetLocs.lo ZGetSender.lo ZGetSubs.lo \
|
||||
ZGetWGPort.lo ZhmStat.lo ZIfNotice.lo ZInit.lo ZLocations.lo \
|
||||
ZMakeAscii.lo ZMkAuth.lo ZNewLocU.lo ZOpenPort.lo ZParseNot.lo \
|
||||
ZPeekIfNot.lo ZPeekNot.lo ZPeekPkt.lo ZPending.lo ZReadAscii.lo \
|
||||
ZRecvNot.lo ZRecvPkt.lo ZRetSubs.lo ZSendList.lo ZSendNot.lo \
|
||||
ZSendPkt.lo ZSendRaw.lo ZSendRLst.lo ZSetDest.lo ZSetFD.lo ZSetSrv.lo \
|
||||
ZSubs.lo ZVariables.lo ZWait4Not.lo Zinternal.lo ZMakeZcode.lo \
|
||||
ZReadZcode.lo ZCkZAut.lo quad_cksum.lo charset.lo ZExpnRlm.lo \
|
||||
ZDumpSession.lo
|
||||
|
||||
.SUFFIXES: .lo
|
||||
|
||||
all: libzephyr.la
|
||||
|
||||
libzephyr.la: ${OBJS}
|
||||
${LIBTOOL} --mode=link ${CC} -rpath ${libdir} -version-info 4:0:0 \
|
||||
${LDFLAGS} -o $@ ${OBJS} ${LIBS}
|
||||
|
||||
${BUILDTOP}/h/zephyr/zephyr_err.h: zephyr_err.c
|
||||
zephyr_err.c: zephyr_err.et
|
||||
compile_et ${srcdir}/zephyr_err.et
|
||||
cp -f zephyr_err.h ${BUILDTOP}/h/zephyr
|
||||
|
||||
.c.lo:
|
||||
${LIBTOOL} --mode=compile ${CC} -c -o $@ ${ALL_CFLAGS} $<
|
||||
|
||||
check:
|
||||
PYTHONPATH=${top_srcdir}/python python $(srcdir)/zephyr_tests.py --builddir=$(BUILDTOP)
|
||||
PYTHONPATH=${top_srcdir}/python $(srcdir)/zephyr_run_doctests --builddir=$(BUILDTOP)
|
||||
|
||||
install: libzephyr.la
|
||||
${LIBTOOL} --mode=install ${INSTALL} -m 644 libzephyr.la \
|
||||
${DESTDIR}${libdir}
|
||||
${INSTALL} -m 644 ${srcdir}/zephyr.1 ${DESTDIR}${mandir}/man1
|
||||
|
||||
clean:
|
||||
rm -f zephyr_err.c zephyr_err.h
|
||||
${LIBTOOL} --mode=clean rm -f ${OBJS} libzephyr.la
|
||||
|
||||
${OBJS}: ${top_srcdir}/h/internal.h ${top_srcdir}/h/sysdep.h
|
||||
${OBJS}: ${BUILDTOP}/h/config.h ${BUILDTOP}/h/zephyr/zephyr.h
|
||||
${OBJS}: ${BUILDTOP}/h/zephyr/zephyr_err.h
|
||||
|
||||
.PHONY: all check install clean
|
||||
|
168
lib/ZAsyncLocate.c
Normal file
168
lib/ZAsyncLocate.c
Normal file
@ -0,0 +1,168 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for asynchronous location functions.
|
||||
*
|
||||
* Created by: Marc Horowitz
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1990,1991 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZAsyncLocate_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
Code_t
|
||||
ZRequestLocations(char *user,
|
||||
register ZAsyncLocateData_t *zald,
|
||||
ZNotice_Kind_t kind, /* UNSAFE, UNACKED, or ACKED */
|
||||
Z_AuthProc auth)
|
||||
{
|
||||
int retval;
|
||||
ZNotice_t notice;
|
||||
|
||||
if (ZGetFD() < 0)
|
||||
if ((retval = ZOpenPort((u_short *)0)) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
(void) memset((char *)¬ice, 0, sizeof(notice));
|
||||
notice.z_kind = kind;
|
||||
notice.z_port = __Zephyr_port;
|
||||
notice.z_class = LOCATE_CLASS;
|
||||
notice.z_class_inst = user;
|
||||
notice.z_opcode = LOCATE_LOCATE;
|
||||
notice.z_sender = 0;
|
||||
notice.z_recipient = "";
|
||||
notice.z_default_format = "";
|
||||
notice.z_message_len = 0;
|
||||
|
||||
if ((retval = ZSendNotice(¬ice, auth)) != ZERR_NONE)
|
||||
return(retval);
|
||||
|
||||
if ((zald->user = (char *) malloc(strlen(user)+1)) == NULL) {
|
||||
return(ENOMEM);
|
||||
}
|
||||
if ((zald->version = (char *) malloc(strlen(notice.z_version)+1)) == NULL) {
|
||||
free(zald->user);
|
||||
return(ENOMEM);
|
||||
}
|
||||
zald->uid = notice.z_multiuid;
|
||||
strcpy(zald->user,user);
|
||||
strcpy(zald->version,notice.z_version);
|
||||
|
||||
return(ZERR_NONE);
|
||||
}
|
||||
|
||||
Code_t
|
||||
ZParseLocations(register ZNotice_t *notice,
|
||||
register ZAsyncLocateData_t *zald,
|
||||
int *nlocs,
|
||||
char **user)
|
||||
{
|
||||
char *ptr, *end;
|
||||
int i;
|
||||
|
||||
ZFlushLocations(); /* This never fails (this function is part of the
|
||||
library, so it is allowed to know this). */
|
||||
|
||||
/* non-matching protocol version numbers means the
|
||||
server is probably an older version--must punt */
|
||||
|
||||
if (zald && strcmp(notice->z_version, zald->version))
|
||||
return(ZERR_VERS);
|
||||
|
||||
if (notice->z_kind == SERVNAK)
|
||||
return (ZERR_SERVNAK);
|
||||
|
||||
/* flag ACKs as special */
|
||||
if (notice->z_kind == SERVACK &&
|
||||
!strcmp(notice->z_opcode, LOCATE_LOCATE)) {
|
||||
*nlocs = -1;
|
||||
return(ZERR_NONE);
|
||||
}
|
||||
|
||||
if (notice->z_kind != ACKED)
|
||||
return (ZERR_INTERNAL);
|
||||
|
||||
end = notice->z_message+notice->z_message_len;
|
||||
|
||||
__locate_num = 0;
|
||||
|
||||
for (ptr=notice->z_message;ptr<end;ptr++)
|
||||
if (!*ptr)
|
||||
__locate_num++;
|
||||
|
||||
__locate_num /= 3;
|
||||
|
||||
if (__locate_num)
|
||||
{
|
||||
__locate_list = (ZLocations_t *)malloc((unsigned)__locate_num*
|
||||
sizeof(ZLocations_t));
|
||||
if (!__locate_list)
|
||||
return (ENOMEM);
|
||||
} else {
|
||||
__locate_list = 0;
|
||||
}
|
||||
|
||||
for (ptr=notice->z_message, i=0; i<__locate_num; i++) {
|
||||
unsigned int len;
|
||||
|
||||
len = strlen (ptr) + 1;
|
||||
__locate_list[i].host = (char *) malloc(len);
|
||||
if (!__locate_list[i].host)
|
||||
return (ENOMEM);
|
||||
(void) strcpy(__locate_list[i].host, ptr);
|
||||
ptr += len;
|
||||
|
||||
len = strlen (ptr) + 1;
|
||||
__locate_list[i].time = (char *) malloc(len);
|
||||
if (!__locate_list[i].time)
|
||||
return (ENOMEM);
|
||||
(void) strcpy(__locate_list[i].time, ptr);
|
||||
ptr += len;
|
||||
|
||||
len = strlen (ptr) + 1;
|
||||
__locate_list[i].tty = (char *) malloc(len);
|
||||
if (!__locate_list[i].tty)
|
||||
return (ENOMEM);
|
||||
(void) strcpy(__locate_list[i].tty, ptr);
|
||||
ptr += len;
|
||||
}
|
||||
|
||||
__locate_next = 0;
|
||||
*nlocs = __locate_num;
|
||||
if (user) {
|
||||
if (zald) {
|
||||
if ((*user = (char *) malloc(strlen(zald->user)+1)) == NULL)
|
||||
return(ENOMEM);
|
||||
strcpy(*user,zald->user);
|
||||
} else {
|
||||
if ((*user = (char *) malloc(strlen(notice->z_class_inst)+1)) == NULL)
|
||||
return(ENOMEM);
|
||||
strcpy(*user,notice->z_class_inst);
|
||||
}
|
||||
}
|
||||
return (ZERR_NONE);
|
||||
}
|
||||
|
||||
int
|
||||
ZCompareALDPred(ZNotice_t *notice,
|
||||
void *zald)
|
||||
{
|
||||
return(ZCompareUID(&(notice->z_multiuid),
|
||||
&(((ZAsyncLocateData_t *) zald)->uid)));
|
||||
}
|
||||
|
||||
void
|
||||
ZFreeALD(register ZAsyncLocateData_t *zald)
|
||||
{
|
||||
if (!zald) return;
|
||||
|
||||
if (zald->user) free(zald->user);
|
||||
if (zald->version) free(zald->version);
|
||||
(void) memset(zald, 0, sizeof(*zald));
|
||||
}
|
67
lib/ZCkAuth.c
Normal file
67
lib/ZCkAuth.c
Normal file
@ -0,0 +1,67 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZCheckAuthentication function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987,1991 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZCheckAuthentication_c[] =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
#if defined(HAVE_KRB5) && !HAVE_KRB5_FREE_DATA
|
||||
#define krb5_free_data(ctx, dat) free((dat)->data)
|
||||
#endif
|
||||
|
||||
/* Check authentication of the notice.
|
||||
If it looks authentic but fails the Kerberos check, return -1.
|
||||
If it looks authentic and passes the Kerberos check, return 1.
|
||||
If it doesn't look authentic, return 0
|
||||
|
||||
When not using Kerberos, return true if the notice claims to be authentic.
|
||||
Only used by clients; the server uses its own routine.
|
||||
*/
|
||||
Code_t
|
||||
ZCheckAuthentication(ZNotice_t *notice,
|
||||
struct sockaddr_in *from)
|
||||
{
|
||||
#if defined(HAVE_KRB4) && !defined(HAVE_KRB5)
|
||||
int result;
|
||||
ZChecksum_t our_checksum;
|
||||
C_Block *session;
|
||||
CREDENTIALS cred;
|
||||
|
||||
/* If the value is already known, return it. */
|
||||
if (notice->z_checked_auth != ZAUTH_UNSET)
|
||||
return (notice->z_checked_auth);
|
||||
|
||||
if (!notice->z_auth)
|
||||
return (ZAUTH_NO);
|
||||
|
||||
if ((result = krb_get_cred(SERVER_SERVICE, SERVER_INSTANCE,
|
||||
__Zephyr_realm, &cred)) != 0)
|
||||
return (ZAUTH_NO);
|
||||
|
||||
session = (C_Block *)cred.session;
|
||||
|
||||
our_checksum = des_quad_cksum((unsigned char *)notice->z_packet,
|
||||
NULL,
|
||||
notice->z_default_format+
|
||||
strlen(notice->z_default_format) + 1
|
||||
- notice->z_packet,
|
||||
0, session);
|
||||
|
||||
/* if mismatched checksum, then the packet was corrupted */
|
||||
return ((our_checksum == notice->z_checksum) ? ZAUTH_YES : ZAUTH_FAILED);
|
||||
#else
|
||||
return ZCheckZcodeAuthentication(notice, from);
|
||||
#endif
|
||||
}
|
57
lib/ZCkIfNot.c
Normal file
57
lib/ZCkIfNot.c
Normal file
@ -0,0 +1,57 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZCheckIfNotice function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZCheckIfNotice_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
Code_t
|
||||
ZCheckIfNotice(ZNotice_t *notice,
|
||||
struct sockaddr_in *from,
|
||||
register int (*predicate)(ZNotice_t *, void *),
|
||||
void *args)
|
||||
{
|
||||
ZNotice_t tmpnotice;
|
||||
Code_t retval;
|
||||
register char *buffer;
|
||||
register struct _Z_InputQ *qptr;
|
||||
|
||||
if ((retval = Z_ReadEnqueue()) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
qptr = Z_GetFirstComplete();
|
||||
|
||||
while (qptr) {
|
||||
if ((retval = ZParseNotice(qptr->packet, qptr->packet_len,
|
||||
&tmpnotice)) != ZERR_NONE)
|
||||
return (retval);
|
||||
if ((*predicate)(&tmpnotice, args)) {
|
||||
if (!(buffer = (char *) malloc((unsigned) qptr->packet_len)))
|
||||
return (ENOMEM);
|
||||
(void) memcpy(buffer, qptr->packet, qptr->packet_len);
|
||||
if (from)
|
||||
*from = qptr->from;
|
||||
if ((retval = ZParseNotice(buffer, qptr->packet_len,
|
||||
notice)) != ZERR_NONE) {
|
||||
free(buffer);
|
||||
return (retval);
|
||||
}
|
||||
Z_RemQueue(qptr);
|
||||
return (ZERR_NONE);
|
||||
}
|
||||
qptr = Z_GetNextComplete(qptr);
|
||||
}
|
||||
|
||||
return (ZERR_NONOTICE);
|
||||
}
|
232
lib/ZCkZAut.c
Normal file
232
lib/ZCkZAut.c
Normal file
@ -0,0 +1,232 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZCheckAuthentication function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Source$
|
||||
* $Author$
|
||||
*
|
||||
* Copyright (c) 1987,1991 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
/* $Header$ */
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZCheckAuthentication_c[] =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
#if defined(HAVE_KRB5) && !HAVE_KRB5_FREE_DATA
|
||||
#define krb5_free_data(ctx, dat) free((dat)->data)
|
||||
#endif
|
||||
|
||||
/* Check authentication of the notice.
|
||||
If it looks authentic but fails the Kerberos check, return -1.
|
||||
If it looks authentic and passes the Kerberos check, return 1.
|
||||
If it doesn't look authentic, return 0
|
||||
|
||||
When not using Kerberos, return true if the notice claims to be authentic.
|
||||
Only used by clients; the server uses its own routine.
|
||||
*/
|
||||
#ifdef HAVE_KRB5
|
||||
static Code_t Z_CheckZcodeAuthentication(ZNotice_t *notice,
|
||||
struct sockaddr_in *from,
|
||||
krb5_keyblock *keyblock)
|
||||
{
|
||||
krb5_error_code result;
|
||||
krb5_enctype enctype;
|
||||
krb5_cksumtype cksumtype;
|
||||
krb5_data cksumbuf;
|
||||
int valid;
|
||||
char *cksum0_base, *cksum1_base = NULL, *cksum2_base;
|
||||
char *x;
|
||||
unsigned char *asn1_data, *key_data, *cksum_data;
|
||||
int asn1_len, key_len, cksum0_len = 0, cksum1_len = 0, cksum2_len = 0;
|
||||
|
||||
/* Figure out what checksum type to use */
|
||||
key_data = Z_keydata(keyblock);
|
||||
key_len = Z_keylen(keyblock);
|
||||
result = Z_ExtractEncCksum(keyblock, &enctype, &cksumtype);
|
||||
if (result) {
|
||||
return (ZAUTH_FAILED);
|
||||
}
|
||||
|
||||
/* Assemble the things to be checksummed */
|
||||
/* first part is from start of packet through z_default_format:
|
||||
* - z_version
|
||||
* - z_num_other_fields
|
||||
* - z_kind
|
||||
* - z_uid
|
||||
* - z_port
|
||||
* - z_auth
|
||||
* - z_authent_len
|
||||
* - z_ascii_authent
|
||||
* - z_class
|
||||
* - z_class_inst
|
||||
* - z_opcode
|
||||
* - z_sender
|
||||
* - z_recipient
|
||||
* - z_default_format
|
||||
*/
|
||||
cksum0_base = notice->z_packet;
|
||||
x = notice->z_default_format;
|
||||
cksum0_len = x + strlen(x) + 1 - cksum0_base;
|
||||
/* second part is from z_multinotice through other fields:
|
||||
* - z_multinotice
|
||||
* - z_multiuid
|
||||
* - z_sender_(sock)addr
|
||||
* - z_charset
|
||||
* - z_other_fields[]
|
||||
*/
|
||||
if (notice->z_num_hdr_fields > 15 ) {
|
||||
cksum1_base = notice->z_multinotice;
|
||||
if (notice->z_num_other_fields)
|
||||
x = notice->z_other_fields[notice->z_num_other_fields - 1];
|
||||
else {
|
||||
/* see also server/kstuff.c:ZCheck{Realm,}Authentication */
|
||||
/* XXXXXXXXXXXXXXXXXXXXXXX */
|
||||
if (notice->z_num_hdr_fields > 16)
|
||||
x = cksum1_base + strlen(cksum1_base) + 1; /* multinotice */
|
||||
if (notice->z_num_hdr_fields > 17)
|
||||
x = x + strlen(x) + 1; /* multiuid */
|
||||
if (notice->z_num_hdr_fields > 18)
|
||||
x = x + strlen(x) + 1; /* sender */
|
||||
}
|
||||
cksum1_len = x + strlen(x) + 1 - cksum1_base; /* charset / extra field */
|
||||
}
|
||||
|
||||
/* last part is the message body */
|
||||
cksum2_base = notice->z_message;
|
||||
cksum2_len = notice->z_message_len;
|
||||
|
||||
/* The following code checks for old-style checksums, which will go
|
||||
away once Kerberos 4 does. */
|
||||
if ((!notice->z_ascii_checksum || *notice->z_ascii_checksum != 'Z') &&
|
||||
key_len == 8 &&
|
||||
(enctype == (krb5_enctype)ENCTYPE_DES_CBC_CRC ||
|
||||
enctype == (krb5_enctype)ENCTYPE_DES_CBC_MD4 ||
|
||||
enctype == (krb5_enctype)ENCTYPE_DES_CBC_MD5)) {
|
||||
/* try old-format checksum (covers cksum0 only) */
|
||||
|
||||
ZChecksum_t our_checksum;
|
||||
|
||||
our_checksum = z_quad_cksum((unsigned char *)cksum0_base, NULL, cksum0_len, 0,
|
||||
key_data);
|
||||
if (our_checksum == notice->z_checksum) {
|
||||
return ZAUTH_YES;
|
||||
}
|
||||
}
|
||||
|
||||
cksumbuf.length = cksum0_len + cksum1_len + cksum2_len;
|
||||
cksumbuf.data = malloc(cksumbuf.length);
|
||||
if (!cksumbuf.data) {
|
||||
return ZAUTH_NO;
|
||||
}
|
||||
/* HOLDING: cksumbuf.data */
|
||||
|
||||
cksum_data = (unsigned char *)cksumbuf.data;
|
||||
memcpy(cksum_data, cksum0_base, cksum0_len);
|
||||
if (cksum1_len)
|
||||
memcpy(cksum_data + cksum0_len, cksum1_base, cksum1_len);
|
||||
memcpy(cksum_data + cksum0_len + cksum1_len,
|
||||
cksum2_base, cksum2_len);
|
||||
|
||||
/* decode zcoded checksum */
|
||||
/* The encoded form is always longer than the original */
|
||||
asn1_len = strlen(notice->z_ascii_checksum) + 1;
|
||||
asn1_data = malloc(asn1_len);
|
||||
if (!asn1_data) {
|
||||
free(cksumbuf.data);
|
||||
return ZAUTH_FAILED;
|
||||
}
|
||||
/* HOLDING: asn1_data, cksumbuf.data */
|
||||
result = ZReadZcode((unsigned char *)notice->z_ascii_checksum,
|
||||
asn1_data, asn1_len, &asn1_len);
|
||||
if (result != ZERR_NONE) {
|
||||
free(asn1_data);
|
||||
free(cksumbuf.data);
|
||||
return ZAUTH_FAILED;
|
||||
}
|
||||
/* HOLDING: asn1_data, cksumbuf.data */
|
||||
|
||||
valid = Z_krb5_verify_cksum(keyblock, &cksumbuf, cksumtype,
|
||||
Z_KEYUSAGE_SRV_CKSUM, asn1_data, asn1_len);
|
||||
|
||||
free(asn1_data);
|
||||
free(cksumbuf.data);
|
||||
|
||||
if (valid)
|
||||
return ZAUTH_YES;
|
||||
else
|
||||
return ZAUTH_FAILED;
|
||||
}
|
||||
#endif
|
||||
|
||||
Code_t ZCheckZcodeAuthentication(ZNotice_t *notice,
|
||||
struct sockaddr_in *from)
|
||||
{
|
||||
#ifdef HAVE_KRB5
|
||||
Code_t answer;
|
||||
krb5_creds *creds;
|
||||
struct _Z_SessionKey *savedkey, *todelete;
|
||||
#endif
|
||||
|
||||
/* If the value is already known, return it. */
|
||||
if (notice->z_checked_auth != ZAUTH_UNSET)
|
||||
return (notice->z_checked_auth);
|
||||
|
||||
if (!notice->z_auth)
|
||||
return (ZAUTH_NO);
|
||||
|
||||
if (!notice->z_ascii_checksum)
|
||||
return (ZAUTH_NO);
|
||||
|
||||
#ifdef HAVE_KRB5
|
||||
/* Try each of the saved session keys. */
|
||||
for (savedkey = Z_keys_head; savedkey != NULL; savedkey = savedkey->next) {
|
||||
answer = Z_CheckZcodeAuthentication(notice, from, savedkey->keyblock);
|
||||
if (answer == ZAUTH_YES) {
|
||||
/* Save the time of the first use of each key. */
|
||||
if (!savedkey->first_use) {
|
||||
savedkey->first_use = time(NULL);
|
||||
} else {
|
||||
/*
|
||||
* Any keys sent sufficiently long before this one is stale. If
|
||||
* we know it has been long enough since the server learned of
|
||||
* this key, we can prune keys made stale by this one.
|
||||
*/
|
||||
if (time(NULL) > savedkey->first_use + KEY_TIMEOUT) {
|
||||
while (Z_keys_tail &&
|
||||
Z_keys_tail->send_time + KEY_TIMEOUT < savedkey->send_time) {
|
||||
todelete = Z_keys_tail;
|
||||
Z_keys_tail = Z_keys_tail->prev;
|
||||
Z_keys_tail->next = NULL;
|
||||
|
||||
krb5_free_keyblock(Z_krb5_ctx, todelete->keyblock);
|
||||
free(todelete);
|
||||
}
|
||||
}
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If each of those fails, pull from the ccache. This is to preserve the
|
||||
* behavior of things like zwgc/zctl where another program actually
|
||||
* generates the subscription notices.
|
||||
*/
|
||||
if (ZGetCreds(&creds))
|
||||
return ZAUTH_NO;
|
||||
|
||||
answer = Z_CheckZcodeAuthentication(notice, from, Z_credskey(creds));
|
||||
|
||||
krb5_free_creds(Z_krb5_ctx, creds);
|
||||
return answer;
|
||||
#else
|
||||
return (notice->z_auth ? ZAUTH_YES : ZAUTH_NO);
|
||||
#endif
|
||||
}
|
29
lib/ZClosePort.c
Normal file
29
lib/ZClosePort.c
Normal file
@ -0,0 +1,29 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZClosePort function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZClosePort_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
Code_t
|
||||
ZClosePort(void)
|
||||
{
|
||||
if (__Zephyr_fd >= 0 && __Zephyr_open)
|
||||
(void) close(__Zephyr_fd);
|
||||
|
||||
__Zephyr_fd = -1;
|
||||
__Zephyr_open = 0;
|
||||
|
||||
return (ZERR_NONE);
|
||||
}
|
24
lib/ZCmpUID.c
Normal file
24
lib/ZCmpUID.c
Normal file
@ -0,0 +1,24 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZCompareUID function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZCompareUID_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
int
|
||||
ZCompareUID(ZUnique_Id_t *uid1,
|
||||
ZUnique_Id_t *uid2)
|
||||
{
|
||||
return (!memcmp((char *)uid1, (char *)uid2, sizeof (*uid1)));
|
||||
}
|
31
lib/ZCmpUIDP.c
Normal file
31
lib/ZCmpUIDP.c
Normal file
@ -0,0 +1,31 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZCompareUIDPred function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZCompareUIDPred_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
int
|
||||
ZCompareUIDPred(ZNotice_t *notice,
|
||||
void *uid)
|
||||
{
|
||||
return (ZCompareUID(¬ice->z_uid, (ZUnique_Id_t *) uid));
|
||||
}
|
||||
|
||||
int
|
||||
ZCompareMultiUIDPred(ZNotice_t *notice,
|
||||
void *uid)
|
||||
{
|
||||
return (ZCompareUID(¬ice->z_multiuid, (ZUnique_Id_t *) uid));
|
||||
}
|
138
lib/ZDumpSession.c
Normal file
138
lib/ZDumpSession.c
Normal file
@ -0,0 +1,138 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the session dump and restore function.
|
||||
*
|
||||
* Created by: David Benjamin
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 2013 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZDumpSession_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
#define SESSION_VERSION 1
|
||||
|
||||
Code_t
|
||||
ZDumpSession(char **buffer,
|
||||
int *ret_len)
|
||||
{
|
||||
#ifdef HAVE_KRB5
|
||||
struct _Z_SessionKey *key;
|
||||
uint32_t num_keys = 0;
|
||||
#endif
|
||||
char *ptr;
|
||||
int len;
|
||||
|
||||
/*
|
||||
* We serialize the port number and all keys. All numbers are
|
||||
* stored in big-endian. Byte strings are prefixed with a 32-bit
|
||||
* length. First field is 16-bit version number. Keys are stored
|
||||
* in reverse.
|
||||
*/
|
||||
|
||||
len = 2 + 2; /* version, port number */
|
||||
#ifdef HAVE_KRB5
|
||||
len += 4; /* num_keys */
|
||||
for (key = Z_keys_head; key != NULL; key = key->next) {
|
||||
num_keys++;
|
||||
len += 4 + 4; /* enctype, length */
|
||||
len += key->keyblock->length; /* contents */
|
||||
}
|
||||
#endif
|
||||
|
||||
*ret_len = len;
|
||||
if (!(*buffer = (char *) malloc((unsigned)*ret_len)))
|
||||
return (ENOMEM);
|
||||
|
||||
ptr = *buffer;
|
||||
*((uint16_t*) ptr) = htons(SESSION_VERSION); ptr += 2;
|
||||
*((uint16_t*) ptr) = htons(__Zephyr_port); ptr += 2;
|
||||
#ifdef HAVE_KRB5
|
||||
*((uint32_t *)ptr) = htonl(num_keys); ptr += 4;
|
||||
for (key = Z_keys_tail; key != NULL; key = key->prev) {
|
||||
*((uint32_t*) ptr) = htonl(key->keyblock->enctype); ptr += 4;
|
||||
*((uint32_t*) ptr) = htonl(key->keyblock->length); ptr += 4;
|
||||
memcpy(ptr, key->keyblock->contents, key->keyblock->length);
|
||||
ptr += key->keyblock->length;
|
||||
}
|
||||
#endif
|
||||
|
||||
return (ZERR_NONE);
|
||||
}
|
||||
|
||||
Code_t
|
||||
ZLoadSession(char *buffer, int len)
|
||||
{
|
||||
#ifdef HAVE_KRB5
|
||||
struct _Z_SessionKey *key;
|
||||
uint32_t num_keys, keylength;
|
||||
krb5_enctype enctype;
|
||||
int i;
|
||||
#endif
|
||||
Code_t ret;
|
||||
uint16_t version, port;
|
||||
|
||||
if (len < 2) return (EINVAL);
|
||||
version = ntohs(*((uint16_t *) buffer)); buffer += 2; len -= 2;
|
||||
if (version != SESSION_VERSION)
|
||||
return (EINVAL);
|
||||
|
||||
if (len < 2) return (EINVAL);
|
||||
port = ntohs(*((uint16_t *) buffer)); buffer += 2; len -= 2;
|
||||
if ((ret = ZOpenPort(&port)) != ZERR_NONE)
|
||||
return ret;
|
||||
|
||||
#ifdef HAVE_KRB5
|
||||
if (len < 4) return (EINVAL);
|
||||
num_keys = ntohl(*((uint32_t *) buffer)); buffer += 4; len -= 4;
|
||||
|
||||
for (i = 0; i < num_keys; i++) {
|
||||
key = (struct _Z_SessionKey *)malloc(sizeof(struct _Z_SessionKey));
|
||||
if (!key)
|
||||
return (ENOMEM);
|
||||
if (len < 4) {
|
||||
free(key);
|
||||
return (EINVAL);
|
||||
}
|
||||
enctype = ntohl(*((uint32_t *) buffer)); buffer += 4; len -= 4;
|
||||
if (len < 4) {
|
||||
free(key);
|
||||
return (EINVAL);
|
||||
}
|
||||
keylength = ntohl(*((uint32_t *) buffer)); buffer += 4; len -= 4;
|
||||
if (len < keylength) {
|
||||
free(key);
|
||||
return (EINVAL);
|
||||
}
|
||||
ret = krb5_init_keyblock(Z_krb5_ctx, enctype, keylength, &key->keyblock);
|
||||
if (ret) {
|
||||
free(key);
|
||||
return ret;
|
||||
}
|
||||
memcpy((char *)key->keyblock->contents, buffer, keylength);
|
||||
buffer += keylength; len -= keylength;
|
||||
/* Just set recent times. It means we might not be able to
|
||||
retire the keys, but that's fine. */
|
||||
key->send_time = time(NULL);
|
||||
key->first_use = time(NULL);
|
||||
/* Prepend to the key list. */
|
||||
key->prev = NULL;
|
||||
key->next = Z_keys_head;
|
||||
if (Z_keys_head)
|
||||
Z_keys_head->prev = key;
|
||||
Z_keys_head = key;
|
||||
if (!Z_keys_tail)
|
||||
Z_keys_tail = key;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (len)
|
||||
return (EINVAL);
|
||||
return (ZERR_NONE);
|
||||
}
|
101
lib/ZExpnRlm.c
Normal file
101
lib/ZExpnRlm.c
Normal file
@ -0,0 +1,101 @@
|
||||
#include <internal.h>
|
||||
#include <sys/param.h>
|
||||
#include <ctype.h>
|
||||
|
||||
char *
|
||||
ZExpandRealm(char *realm)
|
||||
{
|
||||
char *cp1, *cp2;
|
||||
static char expand[REALM_SZ];
|
||||
#ifdef HAVE_KRB5
|
||||
krb5_error_code result;
|
||||
char **list_realms;
|
||||
result = krb5_get_host_realm(Z_krb5_ctx, realm, &list_realms);
|
||||
if (result) {
|
||||
/* Error, just return upper-cased realm */
|
||||
cp2 = realm;
|
||||
cp1 = expand;
|
||||
while (*cp2) {
|
||||
*cp1++ = toupper(*cp2++);
|
||||
}
|
||||
*cp1 = '\0';
|
||||
return expand;
|
||||
}
|
||||
strncpy(expand, list_realms[0], sizeof(expand));
|
||||
expand[sizeof(expand)-1] = '\0';
|
||||
result = krb5_free_host_realm(Z_krb5_ctx, list_realms);
|
||||
return expand;
|
||||
#else
|
||||
#ifndef HAVE_KRB4
|
||||
struct hostent *he;
|
||||
|
||||
he = gethostbyname(realm);
|
||||
|
||||
if (!he || !he->h_name)
|
||||
/* just use the raw realm */
|
||||
cp2 = realm;
|
||||
else
|
||||
cp2 = he->h_name;
|
||||
|
||||
cp1 = expand;
|
||||
while (*cp2) {
|
||||
*cp1++ = toupper(*cp2++);
|
||||
}
|
||||
*cp1 = '\0';
|
||||
|
||||
return(expand);
|
||||
#else
|
||||
int retval;
|
||||
FILE *rlm_file;
|
||||
char krb_host[NS_MAXDNAME + 1];
|
||||
static char krb_realm[REALM_SZ+1];
|
||||
char linebuf[BUFSIZ];
|
||||
char scratch[64];
|
||||
|
||||
/* upcase what we got */
|
||||
cp2 = realm;
|
||||
cp1 = expand;
|
||||
while (*cp2) {
|
||||
*cp1++ = toupper(*cp2++);
|
||||
}
|
||||
*cp1 = '\0';
|
||||
|
||||
if ((rlm_file = fopen("/etc/krb.conf", "r")) == (FILE *) 0) {
|
||||
return(expand);
|
||||
}
|
||||
|
||||
if (fgets(linebuf, BUFSIZ, rlm_file) == NULL) {
|
||||
/* error reading */
|
||||
(void) fclose(rlm_file);
|
||||
return(expand);
|
||||
}
|
||||
|
||||
if (sscanf(linebuf, "%s", krb_realm) < 1) {
|
||||
/* error reading */
|
||||
(void) fclose(rlm_file);
|
||||
return(expand);
|
||||
}
|
||||
|
||||
if (!strncmp(krb_realm, expand, strlen(expand))) {
|
||||
(void) fclose(rlm_file);
|
||||
return(krb_realm);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
/* run through the file, looking for admin host */
|
||||
if (fgets(linebuf, BUFSIZ, rlm_file) == NULL) {
|
||||
(void) fclose(rlm_file);
|
||||
return(expand);
|
||||
}
|
||||
|
||||
if (sscanf(linebuf, "%s %s admin %s", krb_realm, krb_host, scratch)
|
||||
< 2)
|
||||
continue;
|
||||
if (!strncmp(krb_realm, expand, strlen(expand))) {
|
||||
(void) fclose(rlm_file);
|
||||
return(krb_realm);
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_KRB4 */
|
||||
#endif
|
||||
}
|
39
lib/ZFlsLocs.c
Normal file
39
lib/ZFlsLocs.c
Normal file
@ -0,0 +1,39 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZFlushLocations function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZFlushLocations_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
Code_t
|
||||
ZFlushLocations(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!__locate_list)
|
||||
return (ZERR_NONE);
|
||||
|
||||
for (i=0;i<__locate_num;i++) {
|
||||
free(__locate_list[i].host);
|
||||
free(__locate_list[i].time);
|
||||
free(__locate_list[i].tty);
|
||||
}
|
||||
|
||||
free((char *)__locate_list);
|
||||
|
||||
__locate_list = 0;
|
||||
__locate_num = 0;
|
||||
|
||||
return (ZERR_NONE);
|
||||
}
|
40
lib/ZFlsSubs.c
Normal file
40
lib/ZFlsSubs.c
Normal file
@ -0,0 +1,40 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZFlushSubscriptions function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZFlushSubscriptions_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
Code_t
|
||||
ZFlushSubscriptions(void)
|
||||
{
|
||||
register int i;
|
||||
|
||||
if (!__subscriptions_list)
|
||||
return (ZERR_NONE);
|
||||
|
||||
for (i=0;i<__subscriptions_num;i++) {
|
||||
free(__subscriptions_list[i].zsub_class);
|
||||
free(__subscriptions_list[i].zsub_classinst);
|
||||
free(__subscriptions_list[i].zsub_recipient);
|
||||
}
|
||||
|
||||
free((char *)__subscriptions_list);
|
||||
|
||||
__subscriptions_list = 0;
|
||||
__subscriptions_num = 0;
|
||||
|
||||
return (ZERR_NONE);
|
||||
}
|
||||
|
134
lib/ZFmtAuth.c
Normal file
134
lib/ZFmtAuth.c
Normal file
@ -0,0 +1,134 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZFormatAuthenticNotice function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZFormatAuthenticNotice_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
#ifdef HAVE_KRB4
|
||||
Code_t
|
||||
ZFormatAuthenticNotice(ZNotice_t *notice,
|
||||
char *buffer,
|
||||
int buffer_len,
|
||||
int *len,
|
||||
C_Block session)
|
||||
{
|
||||
ZNotice_t newnotice;
|
||||
char *ptr;
|
||||
int retval, hdrlen;
|
||||
|
||||
newnotice = *notice;
|
||||
newnotice.z_auth = 1;
|
||||
newnotice.z_authent_len = 0;
|
||||
newnotice.z_ascii_authent = "";
|
||||
|
||||
if ((retval = Z_FormatRawHeader(&newnotice, buffer, buffer_len,
|
||||
&hdrlen, &ptr, NULL)) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
newnotice.z_checksum =
|
||||
(ZChecksum_t)des_quad_cksum((void *)buffer, NULL, ptr - buffer, 0, (C_Block *)session);
|
||||
|
||||
if ((retval = Z_FormatRawHeader(&newnotice, buffer, buffer_len,
|
||||
&hdrlen, NULL, NULL)) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
ptr = buffer+hdrlen;
|
||||
|
||||
if (newnotice.z_message_len+hdrlen > buffer_len)
|
||||
return (ZERR_PKTLEN);
|
||||
|
||||
(void) memcpy(ptr, newnotice.z_message, newnotice.z_message_len);
|
||||
|
||||
*len = hdrlen+newnotice.z_message_len;
|
||||
|
||||
if (*len > Z_MAXPKTLEN)
|
||||
return (ZERR_PKTLEN);
|
||||
|
||||
return (ZERR_NONE);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_KRB5
|
||||
Code_t
|
||||
ZFormatAuthenticNoticeV5(ZNotice_t *notice,
|
||||
register char *buffer,
|
||||
register int buffer_len,
|
||||
int *len,
|
||||
krb5_keyblock *keyblock)
|
||||
{
|
||||
ZNotice_t newnotice;
|
||||
char *ptr;
|
||||
int retval, hdrlen, hdr_adj;
|
||||
krb5_enctype enctype;
|
||||
krb5_cksumtype cksumtype;
|
||||
#ifdef HAVE_KRB4
|
||||
int key_len;
|
||||
#endif
|
||||
char *cksum_start, *cstart, *cend;
|
||||
int cksum_len;
|
||||
|
||||
#ifdef HAVE_KRB4
|
||||
key_len = Z_keylen(keyblock);
|
||||
#endif
|
||||
retval = Z_ExtractEncCksum(keyblock, &enctype, &cksumtype);
|
||||
if (retval)
|
||||
return (ZAUTH_FAILED);
|
||||
|
||||
#ifdef HAVE_KRB4
|
||||
if (key_len == 8 && (enctype == (krb5_enctype)ENCTYPE_DES_CBC_CRC ||
|
||||
enctype == (krb5_enctype)ENCTYPE_DES_CBC_MD4 ||
|
||||
enctype == (krb5_enctype)ENCTYPE_DES_CBC_MD5)) {
|
||||
C_Block tmp;
|
||||
memcpy(&tmp, Z_keydata(keyblock), key_len);
|
||||
return ZFormatAuthenticNotice(notice, buffer, buffer_len, len,
|
||||
tmp);
|
||||
}
|
||||
#endif
|
||||
|
||||
newnotice = *notice;
|
||||
newnotice.z_auth = 1;
|
||||
newnotice.z_authent_len = 0;
|
||||
newnotice.z_ascii_authent = "";
|
||||
|
||||
if ((retval = Z_NewFormatRawHeader(&newnotice, buffer, buffer_len,
|
||||
&hdrlen,
|
||||
&cksum_start, &cksum_len, &cstart,
|
||||
&cend)) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
/* we know this is only called by the server */
|
||||
retval = Z_InsertZcodeChecksum(keyblock, &newnotice, buffer,
|
||||
cksum_start, cksum_len, cstart, cend,
|
||||
buffer_len, &hdr_adj, 1);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
hdrlen += hdr_adj;
|
||||
|
||||
ptr = buffer+hdrlen;
|
||||
|
||||
if (newnotice.z_message_len+hdrlen > buffer_len)
|
||||
return (ZERR_PKTLEN);
|
||||
|
||||
(void) memcpy(ptr, newnotice.z_message, newnotice.z_message_len);
|
||||
|
||||
*len = hdrlen+newnotice.z_message_len;
|
||||
|
||||
if (*len > Z_MAXPKTLEN)
|
||||
return (ZERR_PKTLEN);
|
||||
|
||||
return (ZERR_NONE);
|
||||
}
|
||||
#endif
|
59
lib/ZFmtList.c
Normal file
59
lib/ZFmtList.c
Normal file
@ -0,0 +1,59 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZFormatNoticeList function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987,1991 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZFormatNoticeList_c[] =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
Code_t
|
||||
ZFormatNoticeList(ZNotice_t *notice,
|
||||
register char **list,
|
||||
int nitems,
|
||||
char **buffer,
|
||||
int *ret_len,
|
||||
Z_AuthProc cert_routine)
|
||||
{
|
||||
char header[Z_MAXHEADERLEN];
|
||||
register int i;
|
||||
int hdrlen, size;
|
||||
char *ptr;
|
||||
Code_t retval;
|
||||
|
||||
if ((retval = Z_FormatHeader(notice, header, sizeof(header), &hdrlen,
|
||||
cert_routine)) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
size = 0;
|
||||
for (i=0;i<nitems;i++)
|
||||
size += strlen(list[i])+1;
|
||||
|
||||
*ret_len = hdrlen+size;
|
||||
|
||||
/* *ret_len can never be zero here, no need to worry about malloc(0). */
|
||||
if (!(*buffer = (char *) malloc((unsigned)*ret_len)))
|
||||
return (ENOMEM);
|
||||
|
||||
(void) memcpy(*buffer, header, hdrlen);
|
||||
|
||||
ptr = *buffer+hdrlen;
|
||||
|
||||
for (;nitems;nitems--, list++) {
|
||||
i = strlen(*list)+1;
|
||||
(void) memcpy(ptr, *list, i);
|
||||
ptr += i;
|
||||
}
|
||||
|
||||
return (ZERR_NONE);
|
||||
}
|
69
lib/ZFmtNotice.c
Normal file
69
lib/ZFmtNotice.c
Normal file
@ -0,0 +1,69 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZFormatNotice function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZFormatNotice_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
Code_t
|
||||
ZFormatNotice(register ZNotice_t *notice,
|
||||
char **buffer,
|
||||
int *ret_len,
|
||||
Z_AuthProc cert_routine)
|
||||
{
|
||||
char header[Z_MAXHEADERLEN];
|
||||
int hdrlen;
|
||||
Code_t retval;
|
||||
|
||||
if ((retval = Z_FormatHeader(notice, header, sizeof(header), &hdrlen,
|
||||
cert_routine)) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
*ret_len = hdrlen+notice->z_message_len;
|
||||
|
||||
/* Length can never be zero, don't have to worry about malloc(0). */
|
||||
if (!(*buffer = (char *) malloc((unsigned)*ret_len)))
|
||||
return (ENOMEM);
|
||||
|
||||
(void) memcpy(*buffer, header, hdrlen);
|
||||
(void) memcpy(*buffer+hdrlen, notice->z_message, notice->z_message_len);
|
||||
|
||||
return (ZERR_NONE);
|
||||
}
|
||||
|
||||
Code_t
|
||||
ZNewFormatNotice(register ZNotice_t *notice,
|
||||
char **buffer,
|
||||
int *ret_len,
|
||||
Z_AuthProc cert_routine)
|
||||
{
|
||||
char header[Z_MAXHEADERLEN];
|
||||
int hdrlen;
|
||||
Code_t retval;
|
||||
|
||||
if ((retval = Z_NewFormatHeader(notice, header, sizeof(header), &hdrlen,
|
||||
cert_routine)) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
*ret_len = hdrlen+notice->z_message_len;
|
||||
|
||||
/* Length can never be zero, don't have to worry about malloc(0). */
|
||||
if (!(*buffer = (char *) malloc((unsigned)*ret_len)))
|
||||
return (ENOMEM);
|
||||
|
||||
(void) memcpy(*buffer, header, hdrlen);
|
||||
(void) memcpy(*buffer+hdrlen, notice->z_message, notice->z_message_len);
|
||||
|
||||
return (ZERR_NONE);
|
||||
}
|
42
lib/ZFmtRaw.c
Normal file
42
lib/ZFmtRaw.c
Normal file
@ -0,0 +1,42 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZFormatRawNotice function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZFormatRawNotice_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
Code_t
|
||||
ZFormatRawNotice(register ZNotice_t *notice,
|
||||
char **buffer,
|
||||
int *ret_len)
|
||||
{
|
||||
char header[Z_MAXHEADERLEN];
|
||||
int hdrlen;
|
||||
Code_t retval;
|
||||
|
||||
if ((retval = Z_FormatRawHeader(notice, header, sizeof(header),
|
||||
&hdrlen, NULL, NULL)) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
*ret_len = hdrlen+notice->z_message_len;
|
||||
|
||||
/* *ret_len is never 0, don't have to worry about malloc(0) */
|
||||
if (!(*buffer = (char *) malloc((unsigned) *ret_len)))
|
||||
return (ENOMEM);
|
||||
|
||||
(void) memcpy(*buffer, header, hdrlen);
|
||||
(void) memcpy(*buffer+hdrlen, notice->z_message, notice->z_message_len);
|
||||
|
||||
return (ZERR_NONE);
|
||||
}
|
55
lib/ZFmtRawLst.c
Normal file
55
lib/ZFmtRawLst.c
Normal file
@ -0,0 +1,55 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZFormatRawNoticeList function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZFormatRawNoticeList_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
Code_t
|
||||
ZFormatRawNoticeList(ZNotice_t *notice,
|
||||
char *list[],
|
||||
int nitems,
|
||||
char **buffer,
|
||||
int *ret_len)
|
||||
{
|
||||
char header[Z_MAXHEADERLEN];
|
||||
int hdrlen, i, size;
|
||||
char *ptr;
|
||||
Code_t retval;
|
||||
|
||||
if ((retval = Z_FormatRawHeader(notice, header, sizeof(header),
|
||||
&hdrlen, NULL, NULL)) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
size = 0;
|
||||
for (i=0;i<nitems;i++)
|
||||
size += strlen(list[i])+1;
|
||||
|
||||
*ret_len = hdrlen+size;
|
||||
|
||||
if (!(*buffer = (char *) malloc((unsigned) *ret_len)))
|
||||
return (ENOMEM);
|
||||
|
||||
(void) memcpy(*buffer, header, hdrlen);
|
||||
|
||||
ptr = *buffer+hdrlen;
|
||||
|
||||
for (;nitems;nitems--, list++) {
|
||||
i = strlen(*list)+1;
|
||||
(void) memcpy(ptr, *list, i);
|
||||
ptr += i;
|
||||
}
|
||||
|
||||
return (ZERR_NONE);
|
||||
}
|
52
lib/ZFmtSmRLst.c
Normal file
52
lib/ZFmtSmRLst.c
Normal file
@ -0,0 +1,52 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZFormatSmallRawNoticeList function.
|
||||
*
|
||||
* Created by: John T. Kohl
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZFormatRawNoticeList_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
Code_t
|
||||
ZFormatSmallRawNoticeList(ZNotice_t *notice,
|
||||
char *list[],
|
||||
int nitems,
|
||||
ZPacket_t buffer,
|
||||
int *ret_len)
|
||||
{
|
||||
Code_t retval;
|
||||
int hdrlen, i, size;
|
||||
char *ptr;
|
||||
|
||||
if ((retval = Z_FormatRawHeader(notice, buffer, Z_MAXHEADERLEN,
|
||||
&hdrlen, NULL, NULL)) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
size = 0;
|
||||
for (i=0;i<nitems;i++)
|
||||
size += strlen(list[i])+1;
|
||||
|
||||
*ret_len = hdrlen+size;
|
||||
|
||||
if (*ret_len > Z_MAXPKTLEN)
|
||||
return (ZERR_PKTLEN);
|
||||
|
||||
ptr = buffer+hdrlen;
|
||||
|
||||
for (;nitems;nitems--, list++) {
|
||||
i = strlen(*list)+1;
|
||||
(void) memcpy(ptr, *list, i);
|
||||
ptr += i;
|
||||
}
|
||||
|
||||
return (ZERR_NONE);
|
||||
}
|
62
lib/ZFmtSmRaw.c
Normal file
62
lib/ZFmtSmRaw.c
Normal file
@ -0,0 +1,62 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZFormatSmallRawNotice function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZFormatRawNotice_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
Code_t
|
||||
ZFormatSmallRawNotice(ZNotice_t *notice,
|
||||
ZPacket_t buffer,
|
||||
int *ret_len)
|
||||
{
|
||||
Code_t retval;
|
||||
int hdrlen;
|
||||
|
||||
if ((retval = Z_FormatRawHeader(notice, buffer, Z_MAXHEADERLEN,
|
||||
&hdrlen, NULL, NULL)) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
*ret_len = hdrlen+notice->z_message_len;
|
||||
|
||||
if (*ret_len > Z_MAXPKTLEN)
|
||||
return (ZERR_PKTLEN);
|
||||
|
||||
(void) memcpy(buffer+hdrlen, notice->z_message, notice->z_message_len);
|
||||
|
||||
return (ZERR_NONE);
|
||||
}
|
||||
|
||||
Code_t
|
||||
ZNewFormatSmallRawNotice(ZNotice_t *notice,
|
||||
ZPacket_t buffer,
|
||||
int *ret_len)
|
||||
{
|
||||
Code_t retval;
|
||||
int hdrlen;
|
||||
|
||||
if ((retval = Z_AsciiFormatRawHeader(notice, buffer, Z_MAXHEADERLEN,
|
||||
&hdrlen, NULL, NULL, NULL, NULL))
|
||||
!= ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
*ret_len = hdrlen+notice->z_message_len;
|
||||
|
||||
if (*ret_len > Z_MAXPKTLEN)
|
||||
return (ZERR_PKTLEN);
|
||||
|
||||
(void) memcpy(buffer+hdrlen, notice->z_message, notice->z_message_len);
|
||||
|
||||
return (ZERR_NONE);
|
||||
}
|
24
lib/ZFreeNot.c
Normal file
24
lib/ZFreeNot.c
Normal file
@ -0,0 +1,24 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZFreeNotice function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZFreeNotice_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
Code_t
|
||||
ZFreeNotice(ZNotice_t *notice)
|
||||
{
|
||||
free(notice->z_packet);
|
||||
return 0;
|
||||
}
|
42
lib/ZGetLocs.c
Normal file
42
lib/ZGetLocs.c
Normal file
@ -0,0 +1,42 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZGetLocations function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZGetLocations_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
#define min(a,b) ((a)<(b)?(a):(b))
|
||||
|
||||
Code_t
|
||||
ZGetLocations(ZLocations_t *location,
|
||||
int *numlocs)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!__locate_list)
|
||||
return (ZERR_NOLOCATIONS);
|
||||
|
||||
if (__locate_next == __locate_num)
|
||||
return (ZERR_NOMORELOCS);
|
||||
|
||||
for (i=0;i<min(*numlocs, __locate_num-__locate_next);i++)
|
||||
location[i] = __locate_list[i+__locate_next];
|
||||
|
||||
if (__locate_num-__locate_next < *numlocs)
|
||||
*numlocs = __locate_num-__locate_next;
|
||||
|
||||
__locate_next += *numlocs;
|
||||
|
||||
return (ZERR_NONE);
|
||||
}
|
77
lib/ZGetSender.c
Normal file
77
lib/ZGetSender.c
Normal file
@ -0,0 +1,77 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZGetSender.c function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987, 1991 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZGetSender_c[] =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
#include <pwd.h>
|
||||
|
||||
char *
|
||||
ZGetSender(void)
|
||||
{
|
||||
struct passwd *pw;
|
||||
static char *sender = NULL;
|
||||
#ifdef HAVE_KRB5
|
||||
krb5_ccache ccache;
|
||||
krb5_principal principal;
|
||||
char *prname;
|
||||
int result;
|
||||
#else
|
||||
#ifdef HAVE_KRB4
|
||||
char pname[ANAME_SZ], pinst[INST_SZ], prealm[REALM_SZ];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Return it if already cached */
|
||||
if (sender)
|
||||
return (sender);
|
||||
|
||||
#ifdef HAVE_KRB5
|
||||
result = krb5_cc_default(Z_krb5_ctx, &ccache);
|
||||
if (!result) {
|
||||
result = krb5_cc_get_principal(Z_krb5_ctx, ccache, &principal);
|
||||
if (!result) {
|
||||
krb5_unparse_name(Z_krb5_ctx, principal, &prname);
|
||||
sender = strdup(prname);
|
||||
krb5_free_unparsed_name(Z_krb5_ctx, prname);
|
||||
krb5_free_principal(Z_krb5_ctx, principal);
|
||||
return sender;
|
||||
}
|
||||
krb5_cc_close(Z_krb5_ctx, ccache);
|
||||
}
|
||||
#else
|
||||
#ifdef HAVE_KRB4
|
||||
if (krb_get_tf_fullname((char *)TKT_FILE, pname, pinst, prealm) == KSUCCESS)
|
||||
{
|
||||
sender = malloc(ANAME_SZ+INST_SZ+REALM_SZ+3);
|
||||
if (sender)
|
||||
(void) sprintf(sender, "%s%s%s@%s", pname, (pinst[0]?".":""),
|
||||
pinst, prealm);
|
||||
return (sender);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* XXX a uid_t is a u_short (now), but getpwuid
|
||||
* wants an int. AARGH! */
|
||||
pw = getpwuid((int) getuid());
|
||||
if (!pw)
|
||||
return ("unknown");
|
||||
sender = malloc(strlen(pw->pw_name) + strlen(__Zephyr_realm) + 2);
|
||||
if (sender)
|
||||
(void) sprintf(sender, "%s@%s", pw->pw_name, __Zephyr_realm);
|
||||
return (sender);
|
||||
}
|
44
lib/ZGetSubs.c
Normal file
44
lib/ZGetSubs.c
Normal file
@ -0,0 +1,44 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZGetSubscriptions function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZGetSubscriptions_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
Code_t
|
||||
ZGetSubscriptions(ZSubscription_t *subscription,
|
||||
int *numsubs)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!__subscriptions_list)
|
||||
return (ZERR_NOSUBSCRIPTIONS);
|
||||
|
||||
if (__subscriptions_next == __subscriptions_num)
|
||||
return (ZERR_NOMORESUBSCRIPTIONS);
|
||||
|
||||
for (i = 0; i < MIN(*numsubs, __subscriptions_num-__subscriptions_next); i++)
|
||||
subscription[i] = __subscriptions_list[i+__subscriptions_next];
|
||||
|
||||
if (__subscriptions_num-__subscriptions_next < *numsubs)
|
||||
*numsubs = __subscriptions_num-__subscriptions_next;
|
||||
|
||||
__subscriptions_next += *numsubs;
|
||||
|
||||
return (ZERR_NONE);
|
||||
}
|
41
lib/ZGetWGPort.c
Normal file
41
lib/ZGetWGPort.c
Normal file
@ -0,0 +1,41 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZGetWGPort function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZGetWGPort_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
int
|
||||
ZGetWGPort(void)
|
||||
{
|
||||
char *envptr, name[128];
|
||||
FILE *fp;
|
||||
int wgport;
|
||||
|
||||
envptr = getenv("WGFILE");
|
||||
if (!envptr) {
|
||||
(void) sprintf(name, "/tmp/wg.%d", getuid());
|
||||
envptr = name;
|
||||
}
|
||||
if (!(fp = fopen(envptr, "r")))
|
||||
return (-1);
|
||||
|
||||
/* if fscanf fails, return -1 via wgport */
|
||||
if (fscanf(fp, "%d", &wgport) != 1)
|
||||
wgport = -1;
|
||||
|
||||
(void) fclose(fp);
|
||||
|
||||
return (wgport);
|
||||
}
|
62
lib/ZIfNotice.c
Normal file
62
lib/ZIfNotice.c
Normal file
@ -0,0 +1,62 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZIfNotice function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZIfNotice_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
Code_t
|
||||
ZIfNotice(ZNotice_t *notice,
|
||||
struct sockaddr_in *from,
|
||||
int (*predicate)(ZNotice_t *, void *),
|
||||
void *args)
|
||||
{
|
||||
ZNotice_t tmpnotice;
|
||||
Code_t retval;
|
||||
char *buffer;
|
||||
struct _Z_InputQ *qptr;
|
||||
|
||||
if ((retval = Z_WaitForComplete()) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
qptr = Z_GetFirstComplete();
|
||||
|
||||
for (;;) {
|
||||
while (qptr) {
|
||||
if ((retval = ZParseNotice(qptr->packet, qptr->packet_len,
|
||||
&tmpnotice)) != ZERR_NONE)
|
||||
return (retval);
|
||||
if ((*predicate)(&tmpnotice, args)) {
|
||||
if (!(buffer = (char *) malloc((unsigned) qptr->packet_len)))
|
||||
return (ENOMEM);
|
||||
(void) memcpy(buffer, qptr->packet, qptr->packet_len);
|
||||
if (from)
|
||||
*from = qptr->from;
|
||||
if ((retval = ZParseNotice(buffer, qptr->packet_len,
|
||||
notice)) != ZERR_NONE) {
|
||||
free(buffer);
|
||||
return (retval);
|
||||
}
|
||||
Z_RemQueue(qptr);
|
||||
return (ZERR_NONE);
|
||||
}
|
||||
qptr = Z_GetNextComplete(qptr);
|
||||
}
|
||||
if ((retval = Z_ReadWait()) != ZERR_NONE)
|
||||
return (retval);
|
||||
qptr = Z_GetFirstComplete(); /* need to look over all of
|
||||
the queued messages, in case
|
||||
a fragment has been reassembled */
|
||||
}
|
||||
}
|
435
lib/ZInit.c
Normal file
435
lib/ZInit.c
Normal file
@ -0,0 +1,435 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZInitialize function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987, 1991 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZInitialize_c[] =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#ifdef HAVE_KRB4
|
||||
#include <krb_err.h>
|
||||
#endif
|
||||
#ifdef HAVE_KRB5
|
||||
#include <krb5.h>
|
||||
#endif
|
||||
|
||||
#ifndef INADDR_NONE
|
||||
#define INADDR_NONE 0xffffffff
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_KRB5) && defined(KRB5_REFERRAL_REALM)
|
||||
#include <profile.h>
|
||||
|
||||
static int z_get_host_realm_replacement(char *, char ***);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_KRB5)
|
||||
int Zauthtype = 5;
|
||||
#elif defined(HAVE_KRB4)
|
||||
int Zauthtype = 4;
|
||||
#else
|
||||
int Zauthtype = 0;
|
||||
#endif
|
||||
|
||||
Code_t
|
||||
ZInitialize(void)
|
||||
{
|
||||
struct servent *hmserv;
|
||||
struct hostent *hostent;
|
||||
char addr[4], hostname[NS_MAXDNAME];
|
||||
struct in_addr servaddr;
|
||||
struct sockaddr_in sin;
|
||||
unsigned int sinsize = sizeof(sin);
|
||||
int s;
|
||||
Code_t code;
|
||||
ZNotice_t notice;
|
||||
#ifdef HAVE_KRB5
|
||||
char **krealms = NULL;
|
||||
#else
|
||||
#ifdef HAVE_KRB4
|
||||
char *krealm = NULL;
|
||||
int krbval;
|
||||
char d1[ANAME_SZ], d2[INST_SZ];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* On OS X you don't need to initialize the Kerberos error tables
|
||||
as long as you link with -framework Kerberos */
|
||||
#if !(defined(__APPLE__) && defined(__MACH__))
|
||||
#ifdef HAVE_KRB4
|
||||
initialize_krb_error_table();
|
||||
#endif
|
||||
#ifdef HAVE_KRB5
|
||||
initialize_krb5_error_table();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
add_error_table(&et_zeph_error_table);
|
||||
#else
|
||||
initialize_zeph_error_table();
|
||||
#endif
|
||||
|
||||
(void) memset((char *)&__HM_addr, 0, sizeof(__HM_addr));
|
||||
|
||||
__HM_addr.sin_family = AF_INET;
|
||||
|
||||
/* Set up local loopback address for HostManager */
|
||||
addr[0] = 127;
|
||||
addr[1] = 0;
|
||||
addr[2] = 0;
|
||||
addr[3] = 1;
|
||||
|
||||
hmserv = (struct servent *)getservbyname(HM_SVCNAME, "udp");
|
||||
__HM_addr.sin_port = (hmserv) ? hmserv->s_port : HM_SVC_FALLBACK;
|
||||
|
||||
(void) memcpy((char *)&__HM_addr.sin_addr, addr, 4);
|
||||
|
||||
__HM_set = 0;
|
||||
|
||||
/* Initialize the input queue */
|
||||
__Q_Tail = NULL;
|
||||
__Q_Head = NULL;
|
||||
|
||||
#ifdef HAVE_KRB5
|
||||
if ((code = krb5_init_context(&Z_krb5_ctx)))
|
||||
return(code);
|
||||
#endif
|
||||
|
||||
/* if the application is a server, there might not be a zhm. The
|
||||
code will fall back to something which might not be "right",
|
||||
but this is is ok, since none of the servers call krb_rd_req. */
|
||||
|
||||
servaddr.s_addr = INADDR_NONE;
|
||||
if (! __Zephyr_server) {
|
||||
if ((code = ZOpenPort(NULL)) != ZERR_NONE)
|
||||
return(code);
|
||||
|
||||
if ((code = ZhmStat(NULL, ¬ice)) != ZERR_NONE)
|
||||
return(code);
|
||||
|
||||
ZClosePort();
|
||||
|
||||
/* the first field, which is NUL-terminated, is the server name.
|
||||
If this code ever support a multiplexing zhm, this will have to
|
||||
be made smarter, and probably per-message */
|
||||
|
||||
#ifdef HAVE_KRB5
|
||||
#ifndef KRB5_REFERRAL_REALM
|
||||
code = krb5_get_host_realm(Z_krb5_ctx, notice.z_message, &krealms);
|
||||
if (code)
|
||||
return(code);
|
||||
#else
|
||||
code = z_get_host_realm_replacement(notice.z_message, &krealms);
|
||||
#endif
|
||||
#else
|
||||
#ifdef HAVE_KRB4
|
||||
krealm = krb_realmofhost(notice.z_message);
|
||||
#endif
|
||||
#endif
|
||||
hostent = gethostbyname(notice.z_message);
|
||||
if (hostent && hostent->h_addrtype == AF_INET)
|
||||
memcpy(&servaddr, hostent->h_addr, sizeof(servaddr));
|
||||
|
||||
ZFreeNotice(¬ice);
|
||||
}
|
||||
|
||||
#ifdef HAVE_KRB5
|
||||
if (krealms) {
|
||||
strcpy(__Zephyr_realm, krealms[0]);
|
||||
krb5_free_host_realm(Z_krb5_ctx, krealms);
|
||||
} else {
|
||||
char *p; /* XXX define this somewhere portable */
|
||||
/* XXX check ticket file here */
|
||||
code = krb5_get_default_realm(Z_krb5_ctx, &p);
|
||||
if (code)
|
||||
return code;
|
||||
strcpy(__Zephyr_realm, p);
|
||||
#ifdef HAVE_KRB5_FREE_DEFAULT_REALM
|
||||
krb5_free_default_realm(Z_krb5_ctx, p);
|
||||
#else
|
||||
free(p);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
#ifdef HAVE_KRB4
|
||||
if (krealm) {
|
||||
strcpy(__Zephyr_realm, krealm);
|
||||
} else if ((krb_get_tf_fullname(TKT_FILE, d1, d2, __Zephyr_realm)
|
||||
!= KSUCCESS) &&
|
||||
((krbval = krb_get_lrealm(__Zephyr_realm, 1)) != KSUCCESS)) {
|
||||
return (krbval);
|
||||
}
|
||||
#else
|
||||
strcpy(__Zephyr_realm, "local-realm");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
__My_addr.s_addr = INADDR_NONE;
|
||||
if (servaddr.s_addr != INADDR_NONE) {
|
||||
/* Try to get the local interface address by connecting a UDP
|
||||
* socket to the server address and getting the local address.
|
||||
* Some broken operating systems (e.g. Solaris 2.0-2.5) yield
|
||||
* INADDR_ANY (zero), so we have to check for that. */
|
||||
s = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s != -1) {
|
||||
memset(&sin, 0, sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
memcpy(&sin.sin_addr, &servaddr, sizeof(servaddr));
|
||||
sin.sin_port = HM_SRV_SVC_FALLBACK;
|
||||
if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) == 0
|
||||
&& getsockname(s, (struct sockaddr *) &sin, &sinsize) == 0
|
||||
&& sin.sin_addr.s_addr != 0)
|
||||
memcpy(&__My_addr, &sin.sin_addr, sizeof(__My_addr));
|
||||
close(s);
|
||||
}
|
||||
}
|
||||
if (__My_addr.s_addr == INADDR_NONE) {
|
||||
/* We couldn't figure out the local interface address by the
|
||||
* above method. Try by resolving the local hostname. (This
|
||||
* is a pretty broken thing to do, and unfortunately what we
|
||||
* always do on server machines.) */
|
||||
if (gethostname(hostname, sizeof(hostname)) == 0) {
|
||||
hostent = gethostbyname(hostname);
|
||||
if (hostent && hostent->h_addrtype == AF_INET)
|
||||
memcpy(&__My_addr, hostent->h_addr, sizeof(__My_addr));
|
||||
}
|
||||
}
|
||||
/* If the above methods failed, zero out __My_addr so things will
|
||||
* sort of kind of work. */
|
||||
if (__My_addr.s_addr == INADDR_NONE)
|
||||
__My_addr.s_addr = 0;
|
||||
|
||||
/* Get the sender so we can cache it */
|
||||
(void) ZGetSender();
|
||||
|
||||
return (ZERR_NONE);
|
||||
}
|
||||
|
||||
const char * ZGetRealm (void) {
|
||||
return __Zephyr_realm;
|
||||
}
|
||||
|
||||
int ZGetFD (void) {
|
||||
return __Zephyr_fd;
|
||||
}
|
||||
|
||||
int ZQLength (void) {
|
||||
return __Q_CompleteLength;
|
||||
}
|
||||
|
||||
struct sockaddr_in ZGetDestAddr (void) {
|
||||
return __HM_addr;
|
||||
}
|
||||
|
||||
#if defined(HAVE_KRB5) && defined(KRB5_REFERRAL_REALM)
|
||||
#include <ctype.h>
|
||||
#include <netinet/in.h>
|
||||
#include <resolv.h>
|
||||
|
||||
static int txt_lookup(char *qname, char **result) {
|
||||
int ret, buflen, left;
|
||||
void *buf = NULL;
|
||||
void *bufend = NULL;
|
||||
HEADER *hdr;
|
||||
unsigned char *p;
|
||||
char dname[NS_MAXDNAME];
|
||||
int queries, answers;
|
||||
|
||||
ret = res_init();
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
buflen = 0;
|
||||
do {
|
||||
buflen = buflen ? buflen * 2 : 2048;
|
||||
buf = (buf == NULL) ? malloc(buflen) : realloc(buf, buflen);
|
||||
|
||||
ret = res_search(qname, C_IN, T_TXT, buf, buflen);
|
||||
} while (ret > buflen);
|
||||
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
buflen = ret;
|
||||
left = ret;
|
||||
bufend = buflen + (unsigned char *)buf;
|
||||
|
||||
hdr = (HEADER *)buf;
|
||||
p = buf;
|
||||
queries = ntohs(hdr->qdcount);
|
||||
answers = ntohs(hdr->ancount);
|
||||
p += sizeof (HEADER);
|
||||
left -= sizeof (HEADER);
|
||||
|
||||
while (queries--) {
|
||||
ret = dn_expand(buf, bufend, p, dname, sizeof dname);
|
||||
if (ret < 0 || (ret + 4) > left)
|
||||
return -1;
|
||||
p += ret + 4;
|
||||
left -= ret + 4;
|
||||
}
|
||||
|
||||
if (!ret || !answers)
|
||||
return -1;
|
||||
|
||||
while (answers--) {
|
||||
int class, type;
|
||||
|
||||
ret = dn_expand(buf, bufend, p, dname, sizeof dname);
|
||||
if (ret < 0 || ret > left)
|
||||
return -1;
|
||||
p += ret;
|
||||
left -= ret;
|
||||
|
||||
if (left < 10)
|
||||
return -1;
|
||||
type = ntohs(*(uint16_t *)p);
|
||||
p += 2;
|
||||
class = ntohs(*(uint16_t *)p);
|
||||
p += 6;
|
||||
ret = ntohs(*(uint16_t *)p);
|
||||
p += 2;
|
||||
left -= 10;
|
||||
|
||||
if (ret > left)
|
||||
return -1;
|
||||
|
||||
if (class == C_IN && type == T_TXT) {
|
||||
*result = malloc(ret);
|
||||
if (*result == NULL)
|
||||
return -1;
|
||||
memcpy(*result, p + 1, ret - 1);
|
||||
(*result)[ret - 1] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
p += ret;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
z_get_host_realm_replacement(char *inhost, char ***krealms) {
|
||||
char *host, *p;
|
||||
char *realm = NULL;
|
||||
char *default_realm = NULL;
|
||||
char *tmp_realm;
|
||||
char *qname;
|
||||
profile_t prof;
|
||||
int ret;
|
||||
|
||||
host = strdup(inhost);
|
||||
|
||||
for (p = host; *p; p++)
|
||||
if (isupper(*p))
|
||||
*p = tolower(*p);
|
||||
|
||||
p = host;
|
||||
while (p && !default_realm) {
|
||||
if (*p == '.') {
|
||||
p++;
|
||||
if (default_realm == NULL) {
|
||||
default_realm = p;
|
||||
}
|
||||
} else {
|
||||
p = strchr(p, '.');
|
||||
}
|
||||
}
|
||||
|
||||
p = host;
|
||||
tmp_realm = NULL;
|
||||
|
||||
krb5_get_profile(Z_krb5_ctx, &prof);
|
||||
while(p) {
|
||||
ret = profile_get_string(prof, "domain_realm", p,
|
||||
0, NULL, &tmp_realm);
|
||||
if (ret) {
|
||||
profile_abandon(prof);
|
||||
free(host);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (tmp_realm != NULL)
|
||||
break;
|
||||
|
||||
if (*p == '.')
|
||||
p++;
|
||||
else
|
||||
p = strchr(p, '.');
|
||||
}
|
||||
|
||||
if (tmp_realm != NULL) {
|
||||
realm = strdup(tmp_realm);
|
||||
profile_release_string(tmp_realm);
|
||||
if (realm == NULL) {
|
||||
free(host);
|
||||
return errno;
|
||||
}
|
||||
}
|
||||
profile_abandon(prof);
|
||||
|
||||
if (realm == NULL) {
|
||||
p = host;
|
||||
do {
|
||||
qname = malloc(strlen(p) + strlen("_kerberos..") + 1);
|
||||
if (qname == NULL) {
|
||||
free(host);
|
||||
return errno;
|
||||
}
|
||||
sprintf(qname, "_kerberos.%s.", p);
|
||||
ret = txt_lookup(qname, &realm);
|
||||
free(qname);
|
||||
|
||||
p = strchr(p,'.');
|
||||
if (p)
|
||||
p++;
|
||||
} while (ret && p && p[0]);
|
||||
}
|
||||
|
||||
if (realm == NULL) {
|
||||
if (default_realm != NULL) {
|
||||
realm = strdup(default_realm);
|
||||
if (realm == NULL) {
|
||||
free(host);
|
||||
return errno;
|
||||
}
|
||||
|
||||
for (p = realm; *p; p++)
|
||||
if (islower(*p))
|
||||
*p = toupper(*p);
|
||||
} else {
|
||||
ret = krb5_get_default_realm(Z_krb5_ctx, &realm);
|
||||
if (ret) {
|
||||
free(host);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(host);
|
||||
|
||||
if ((*krealms = calloc(2, sizeof(*krealms))) == NULL) {
|
||||
if (realm)
|
||||
free(realm);
|
||||
return errno;
|
||||
}
|
||||
|
||||
(*krealms)[0] = realm;
|
||||
(*krealms)[1] = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
192
lib/ZLocations.c
Normal file
192
lib/ZLocations.c
Normal file
@ -0,0 +1,192 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZSetLocation, ZUnsetLocation, and
|
||||
* ZFlushMyLocations functions.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987,1988,1991 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZLocations_c[] =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
#include <pwd.h>
|
||||
|
||||
static char host[NS_MAXDNAME], *mytty = "space";
|
||||
static int location_info_set = 0;
|
||||
|
||||
Code_t
|
||||
ZInitLocationInfo(char *hostname,
|
||||
char *tty)
|
||||
{
|
||||
char *ttyp, *p;
|
||||
struct hostent *hent;
|
||||
|
||||
if (hostname) {
|
||||
strcpy(host, hostname);
|
||||
} else {
|
||||
if (gethostname(host, sizeof(host)) < 0)
|
||||
return (errno);
|
||||
hent = gethostbyname(host);
|
||||
if (hent) {
|
||||
(void) strncpy(host, hent->h_name, sizeof(host));
|
||||
host[sizeof(host) - 1] = '\0';
|
||||
}
|
||||
}
|
||||
if (tty) {
|
||||
mytty = strdup(tty);
|
||||
} else {
|
||||
ttyp = ttyname(0);
|
||||
if (ttyp && *ttyp) {
|
||||
p = strchr(ttyp + 1, '/');
|
||||
mytty = strdup(p ? p + 1 : ttyp);
|
||||
} else {
|
||||
mytty = strdup("unknown");
|
||||
}
|
||||
}
|
||||
if (mytty == NULL)
|
||||
return errno;
|
||||
location_info_set = 1;
|
||||
return (ZERR_NONE);
|
||||
}
|
||||
|
||||
Code_t
|
||||
ZSetLocation(char *exposure)
|
||||
{
|
||||
return (Z_SendLocation(LOGIN_CLASS, exposure, ZGetSender(), ZAUTH,
|
||||
"$sender logged in to $1 on $3 at $2"));
|
||||
}
|
||||
|
||||
Code_t
|
||||
ZUnsetLocation(void)
|
||||
{
|
||||
return (Z_SendLocation(LOGIN_CLASS, LOGIN_USER_LOGOUT, ZGetSender(),
|
||||
ZNOAUTH, "$sender logged out of $1 on $3 at $2"));
|
||||
}
|
||||
|
||||
Code_t
|
||||
ZFlushMyLocations(void)
|
||||
{
|
||||
return (Z_SendLocation(LOGIN_CLASS, LOGIN_USER_FLUSH, ZGetSender(),
|
||||
ZAUTH, ""));
|
||||
}
|
||||
|
||||
Code_t
|
||||
ZFlushUserLocations(char *target)
|
||||
{
|
||||
return (Z_SendLocation(LOGIN_CLASS, LOGIN_USER_FLUSH, target, ZAUTH, ""));
|
||||
}
|
||||
|
||||
char *
|
||||
ZParseExposureLevel(char *text)
|
||||
{
|
||||
if (!strcasecmp(text, EXPOSE_NONE))
|
||||
return (EXPOSE_NONE);
|
||||
else if (!strcasecmp(text, EXPOSE_OPSTAFF))
|
||||
return (EXPOSE_OPSTAFF);
|
||||
else if (!strcasecmp(text, EXPOSE_REALMVIS))
|
||||
return (EXPOSE_REALMVIS);
|
||||
else if (!strcasecmp(text, EXPOSE_REALMANN))
|
||||
return (EXPOSE_REALMANN);
|
||||
else if (!strcasecmp(text, EXPOSE_NETVIS))
|
||||
return (EXPOSE_NETVIS);
|
||||
else if (!strcasecmp(text, EXPOSE_NETANN))
|
||||
return (EXPOSE_NETANN);
|
||||
else
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* lifted from lib/ZSendPkt.c wait_for_hmack, but waits for SERVACK instead */
|
||||
static int
|
||||
wait_for_srvack(ZNotice_t *notice, void *uid)
|
||||
{
|
||||
return ((notice->z_kind == SERVACK || notice->z_kind == SERVNAK)
|
||||
&& ZCompareUID(¬ice->z_uid, (ZUnique_Id_t *)uid));
|
||||
}
|
||||
|
||||
Code_t
|
||||
Z_SendLocation(char *class,
|
||||
char *opcode,
|
||||
char *target,
|
||||
Z_AuthProc auth,
|
||||
char *format)
|
||||
{
|
||||
int retval;
|
||||
time_t ourtime;
|
||||
ZNotice_t notice, retnotice;
|
||||
char *bptr[3];
|
||||
short wg_port = ZGetWGPort();
|
||||
|
||||
if (!location_info_set)
|
||||
ZInitLocationInfo(NULL, NULL);
|
||||
|
||||
memset((char *)¬ice, 0, sizeof(notice));
|
||||
notice.z_kind = ACKED;
|
||||
notice.z_port = (u_short) ((wg_port == -1) ? 0 : wg_port);
|
||||
notice.z_class = class;
|
||||
notice.z_class_inst = target;
|
||||
notice.z_opcode = opcode;
|
||||
notice.z_sender = 0;
|
||||
notice.z_recipient = "";
|
||||
notice.z_num_other_fields = 0;
|
||||
notice.z_default_format = format;
|
||||
|
||||
bptr[0] = host;
|
||||
ourtime = time((time_t *)0);
|
||||
bptr[1] = ctime(&ourtime);
|
||||
bptr[1][strlen(bptr[1])-1] = '\0';
|
||||
bptr[2] = mytty;
|
||||
|
||||
if ((retval = ZSendList(¬ice, bptr, 3, auth)) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
retval = Z_WaitForNotice (&retnotice, wait_for_srvack, ¬ice.z_uid,
|
||||
SRV_TIMEOUT);
|
||||
if (retval != ZERR_NONE)
|
||||
return retval;
|
||||
|
||||
if (retnotice.z_kind == SERVNAK) {
|
||||
if (!retnotice.z_message_len) {
|
||||
ZFreeNotice(&retnotice);
|
||||
return (ZERR_SERVNAK);
|
||||
}
|
||||
if (!strcmp(retnotice.z_message, ZSRVACK_NOTSENT)) {
|
||||
ZFreeNotice(&retnotice);
|
||||
return (ZERR_AUTHFAIL);
|
||||
}
|
||||
if (!strcmp(retnotice.z_message, ZSRVACK_FAIL)) {
|
||||
ZFreeNotice(&retnotice);
|
||||
return (ZERR_LOGINFAIL);
|
||||
}
|
||||
ZFreeNotice(&retnotice);
|
||||
return (ZERR_SERVNAK);
|
||||
}
|
||||
|
||||
if (retnotice.z_kind != SERVACK) {
|
||||
ZFreeNotice(&retnotice);
|
||||
return (ZERR_INTERNAL);
|
||||
}
|
||||
|
||||
if (!retnotice.z_message_len) {
|
||||
ZFreeNotice(&retnotice);
|
||||
return (ZERR_INTERNAL);
|
||||
}
|
||||
|
||||
if (strcmp(retnotice.z_message, ZSRVACK_SENT) &&
|
||||
strcmp(retnotice.z_message, ZSRVACK_NOTSENT)) {
|
||||
ZFreeNotice(&retnotice);
|
||||
return (ZERR_INTERNAL);
|
||||
}
|
||||
|
||||
ZFreeNotice(&retnotice);
|
||||
|
||||
return (ZERR_NONE);
|
||||
}
|
92
lib/ZMakeAscii.c
Normal file
92
lib/ZMakeAscii.c
Normal file
@ -0,0 +1,92 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZMakeAscii function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#include <internal.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZMakeAscii_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
static char *itox_chars = "0123456789ABCDEF";
|
||||
|
||||
Code_t
|
||||
ZMakeAscii(register char *ptr,
|
||||
int len,
|
||||
unsigned char *field,
|
||||
int num)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0;i<num;i++) {
|
||||
/* we need to add "0x" if we are between 4 byte pieces */
|
||||
if ((i & 3) == 0) {
|
||||
if (len < (i?4:3))
|
||||
return ZERR_FIELDLEN;
|
||||
/* except at the beginning, put a space in before the "0x" */
|
||||
if (i) {
|
||||
*ptr++ = ' ';
|
||||
len--;
|
||||
}
|
||||
*ptr++ = '0';
|
||||
*ptr++ = 'x';
|
||||
len -= 2;
|
||||
}
|
||||
if (len < 3)
|
||||
return ZERR_FIELDLEN;
|
||||
*ptr++ = itox_chars[(int) (field[i] >> 4)];
|
||||
*ptr++ = itox_chars[(int) (field[i] & 0xf)];
|
||||
len -= 2;
|
||||
}
|
||||
|
||||
*ptr = '\0';
|
||||
return ZERR_NONE;
|
||||
}
|
||||
|
||||
Code_t
|
||||
ZMakeAscii32(register char *ptr,
|
||||
int len,
|
||||
unsigned long value)
|
||||
{
|
||||
if (len < 11)
|
||||
return ZERR_FIELDLEN;
|
||||
*ptr++ = '0';
|
||||
*ptr++ = 'x';
|
||||
*ptr++ = itox_chars[(value >> 28) & 0xf];
|
||||
*ptr++ = itox_chars[(value >> 24) & 0xf];
|
||||
*ptr++ = itox_chars[(value >> 20) & 0xf];
|
||||
*ptr++ = itox_chars[(value >> 16) & 0xf];
|
||||
*ptr++ = itox_chars[(value >> 12) & 0xf];
|
||||
*ptr++ = itox_chars[(value >> 8) & 0xf];
|
||||
*ptr++ = itox_chars[(value >> 4) & 0xf];
|
||||
*ptr++ = itox_chars[(value >> 0) & 0xf];
|
||||
*ptr = 0;
|
||||
return ZERR_NONE;
|
||||
}
|
||||
|
||||
Code_t
|
||||
ZMakeAscii16(register char *ptr,
|
||||
int len,
|
||||
unsigned int value)
|
||||
{
|
||||
if (len < 7)
|
||||
return ZERR_FIELDLEN;
|
||||
*ptr++ = '0';
|
||||
*ptr++ = 'x';
|
||||
*ptr++ = itox_chars[(value >> 12) & 0xf];
|
||||
*ptr++ = itox_chars[(value >> 8) & 0xf];
|
||||
*ptr++ = itox_chars[(value >> 4) & 0xf];
|
||||
*ptr++ = itox_chars[(value >> 0) & 0xf];
|
||||
*ptr = 0;
|
||||
return ZERR_NONE;
|
||||
}
|
||||
|
80
lib/ZMakeZcode.c
Normal file
80
lib/ZMakeZcode.c
Normal file
@ -0,0 +1,80 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZMakeZcode function.
|
||||
*
|
||||
* Created by: Jeffrey Hutzelman
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987, 2002 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#include <internal.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZMakeZcode_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
Code_t
|
||||
ZMakeZcode32(char *ptr,
|
||||
int len,
|
||||
unsigned long val)
|
||||
{
|
||||
unsigned char buf[4];
|
||||
buf[0] = (val >> 24) & 0xff;
|
||||
buf[1] = (val >> 16) & 0xff;
|
||||
buf[2] = (val >> 8) & 0xff;
|
||||
buf[3] = val & 0xff;
|
||||
return ZMakeZcode(ptr, len, buf, 4);
|
||||
}
|
||||
|
||||
Code_t
|
||||
ZMakeZcode(register char *ptr,
|
||||
int len,
|
||||
unsigned char *field,
|
||||
int num)
|
||||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
* This optimistic check lets us discover quickly if the buffer
|
||||
* is not even large enough to hold the field without escapes.
|
||||
* It also insures we'll have space for the leading 'Z' and the
|
||||
* trailing NUL. Note that this does _not_ remove the need for
|
||||
* checking length as we encode.
|
||||
*/
|
||||
if (len < num + 2)
|
||||
return ZERR_FIELDLEN;
|
||||
*ptr++ = 'Z';
|
||||
--len;
|
||||
for (i=0;i<num;i++) {
|
||||
switch (field[i]) {
|
||||
case 0x00:
|
||||
if (len < 3)
|
||||
return ZERR_FIELDLEN;
|
||||
*(unsigned char *)ptr++ = 0xff;
|
||||
*(unsigned char *)ptr++ = 0xf0;
|
||||
len -= 2;
|
||||
continue;
|
||||
|
||||
case 0xff:
|
||||
if (len < 3)
|
||||
return ZERR_FIELDLEN;
|
||||
*(unsigned char *)ptr++ = 0xff;
|
||||
*(unsigned char *)ptr++ = 0xf1;
|
||||
len -= 2;
|
||||
continue;
|
||||
|
||||
default:
|
||||
if (len < 2)
|
||||
return ZERR_FIELDLEN;
|
||||
*ptr++ = field[i];
|
||||
len--;
|
||||
}
|
||||
}
|
||||
|
||||
*ptr = '\0';
|
||||
return ZERR_NONE;
|
||||
}
|
327
lib/ZMkAuth.c
Normal file
327
lib/ZMkAuth.c
Normal file
@ -0,0 +1,327 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZMakeAuthentication function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZMakeAuthentication_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_KRB4
|
||||
#include <krb_err.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_KRB5) && !HAVE_KRB5_FREE_DATA
|
||||
#define krb5_free_data(ctx, dat) free((dat)->data)
|
||||
#endif
|
||||
|
||||
Code_t
|
||||
ZResetAuthentication(void)
|
||||
{
|
||||
return ZERR_NONE;
|
||||
}
|
||||
|
||||
Code_t
|
||||
ZMakeAuthentication(register ZNotice_t *notice,
|
||||
char *buffer,
|
||||
int buffer_len,
|
||||
int *len)
|
||||
{
|
||||
#ifdef HAVE_KRB5
|
||||
return ZMakeZcodeAuthentication(notice, buffer, buffer_len, len/*?XXX*/);
|
||||
#else
|
||||
#ifdef HAVE_KRB4
|
||||
int result;
|
||||
KTEXT_ST authent;
|
||||
char *cstart, *cend;
|
||||
ZChecksum_t checksum;
|
||||
CREDENTIALS cred;
|
||||
C_Block *session;
|
||||
|
||||
result = krb_mk_req(&authent, SERVER_SERVICE,
|
||||
SERVER_INSTANCE, __Zephyr_realm, 0);
|
||||
if (result != MK_AP_OK)
|
||||
return (result+krb_err_base);
|
||||
result = krb_get_cred(SERVER_SERVICE, SERVER_INSTANCE,
|
||||
__Zephyr_realm, &cred);
|
||||
if (result != KSUCCESS)
|
||||
return (result+krb_err_base);
|
||||
|
||||
session = (C_Block *)cred.session;
|
||||
|
||||
notice->z_auth = 1;
|
||||
notice->z_authent_len = authent.length;
|
||||
notice->z_ascii_authent = (char *)malloc((unsigned)authent.length*3);
|
||||
/* zero length authent is an error, so malloc(0) is not a problem */
|
||||
if (!notice->z_ascii_authent)
|
||||
return (ENOMEM);
|
||||
if ((result = ZMakeAscii(notice->z_ascii_authent,
|
||||
authent.length*3,
|
||||
authent.dat,
|
||||
authent.length)) != ZERR_NONE) {
|
||||
free(notice->z_ascii_authent);
|
||||
return (result);
|
||||
}
|
||||
result = Z_FormatRawHeader(notice, buffer, buffer_len, len, &cstart,
|
||||
&cend);
|
||||
free(notice->z_ascii_authent);
|
||||
notice->z_authent_len = 0;
|
||||
if (result)
|
||||
return(result);
|
||||
|
||||
/* Compute a checksum over the header and message. */
|
||||
checksum = des_quad_cksum((unsigned char *)buffer, NULL, cstart - buffer, 0, session);
|
||||
checksum ^= des_quad_cksum((unsigned char *)cend, NULL, buffer + *len - cend, 0,
|
||||
session);
|
||||
checksum ^= des_quad_cksum((unsigned char *)notice->z_message, NULL, notice->z_message_len,
|
||||
0, session);
|
||||
notice->z_checksum = checksum;
|
||||
ZMakeAscii32(cstart, buffer + buffer_len - cstart, checksum);
|
||||
|
||||
return (ZERR_NONE);
|
||||
#else
|
||||
notice->z_checksum = 0;
|
||||
notice->z_auth = 1;
|
||||
notice->z_authent_len = 0;
|
||||
notice->z_ascii_authent = "";
|
||||
return (Z_FormatRawHeader(notice, buffer, buffer_len, len, NULL, NULL));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
Code_t
|
||||
Z_MakeAuthenticationSaveKey(register ZNotice_t *notice,
|
||||
char *buffer,
|
||||
int buffer_len,
|
||||
int *len)
|
||||
{
|
||||
#ifndef HAVE_KRB5
|
||||
/* Key management not implemented for krb4. */
|
||||
return ZMakeAuthentication(notice, buffer, buffer_len, len);
|
||||
#else
|
||||
Code_t result;
|
||||
krb5_creds *creds = NULL;
|
||||
krb5_keyblock *keyblock;
|
||||
struct _Z_SessionKey *savedkey;
|
||||
|
||||
/* Look up creds and checksum the notice. */
|
||||
if ((result = ZGetCreds(&creds)))
|
||||
return result;
|
||||
if ((result = Z_MakeZcodeAuthentication(notice, buffer, buffer_len, len,
|
||||
creds))) {
|
||||
krb5_free_creds(Z_krb5_ctx, creds);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Save the key. */
|
||||
keyblock = Z_credskey(creds);
|
||||
|
||||
if (Z_keys_head &&
|
||||
Z_keys_head->keyblock->enctype == keyblock->enctype &&
|
||||
Z_keys_head->keyblock->length == keyblock->length &&
|
||||
memcmp(Z_keys_head->keyblock->contents, keyblock->contents,
|
||||
keyblock->length) == 0) {
|
||||
/*
|
||||
* Optimization: if the key hasn't changed, replace the current entry,
|
||||
* rather than make a new one.
|
||||
*/
|
||||
Z_keys_head->send_time = time(NULL);
|
||||
Z_keys_head->first_use = 0;
|
||||
} else {
|
||||
savedkey = (struct _Z_SessionKey *)malloc(sizeof(struct _Z_SessionKey));
|
||||
if (!savedkey) {
|
||||
krb5_free_creds(Z_krb5_ctx, creds);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
if ((result = krb5_copy_keyblock(Z_krb5_ctx, keyblock, &savedkey->keyblock))) {
|
||||
free(savedkey);
|
||||
krb5_free_creds(Z_krb5_ctx, creds);
|
||||
return result;
|
||||
}
|
||||
savedkey->send_time = time(NULL);
|
||||
savedkey->first_use = 0;
|
||||
|
||||
savedkey->prev = NULL;
|
||||
savedkey->next = Z_keys_head;
|
||||
if (Z_keys_head)
|
||||
Z_keys_head->prev = savedkey;
|
||||
Z_keys_head = savedkey;
|
||||
if (!Z_keys_tail)
|
||||
Z_keys_tail = savedkey;
|
||||
}
|
||||
|
||||
krb5_free_creds(Z_krb5_ctx, creds);
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* only used by server? */
|
||||
Code_t
|
||||
ZMakeZcodeAuthentication(register ZNotice_t *notice,
|
||||
char *buffer,
|
||||
int buffer_len,
|
||||
int *phdr_len)
|
||||
{
|
||||
return ZMakeZcodeRealmAuthentication(notice, buffer, buffer_len, phdr_len,
|
||||
__Zephyr_realm);
|
||||
}
|
||||
|
||||
Code_t
|
||||
ZMakeZcodeRealmAuthentication(register ZNotice_t *notice,
|
||||
char *buffer,
|
||||
int buffer_len,
|
||||
int *phdr_len,
|
||||
char *realm)
|
||||
{
|
||||
#ifdef HAVE_KRB5
|
||||
Code_t result;
|
||||
krb5_creds *creds = NULL;
|
||||
|
||||
result = ZGetCredsRealm(&creds, realm);
|
||||
if (!result)
|
||||
result = Z_MakeZcodeAuthentication(notice, buffer, buffer_len, phdr_len,
|
||||
creds);
|
||||
if (creds != NULL)
|
||||
krb5_free_creds(Z_krb5_ctx, creds);
|
||||
return result;
|
||||
#else /* HAVE_KRB5 */
|
||||
return ZERR_INTERNAL;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_KRB5
|
||||
Code_t
|
||||
Z_MakeZcodeAuthentication(register ZNotice_t *notice,
|
||||
char *buffer,
|
||||
int buffer_len,
|
||||
int *phdr_len,
|
||||
krb5_creds *creds)
|
||||
{
|
||||
krb5_error_code result = 0;
|
||||
krb5_keyblock *keyblock;
|
||||
krb5_auth_context authctx;
|
||||
krb5_data *authent;
|
||||
char *cksum_start, *cstart, *cend;
|
||||
int cksum_len, zcode_len = 0, phdr_adj = 0;
|
||||
|
||||
notice->z_ascii_authent = NULL;
|
||||
|
||||
keyblock = Z_credskey(creds);
|
||||
|
||||
authent = (krb5_data *)malloc(sizeof(krb5_data));
|
||||
if (authent == NULL)
|
||||
result = ENOMEM;
|
||||
authent->data = NULL; /* so that we can blithely krb5_fre_data_contents on
|
||||
the way out */
|
||||
|
||||
if (!result)
|
||||
result = krb5_auth_con_init(Z_krb5_ctx, &authctx);
|
||||
|
||||
if (!result) {
|
||||
result = krb5_mk_req_extended(Z_krb5_ctx, &authctx, 0 /* options */,
|
||||
0 /* in_data */, creds, authent);
|
||||
krb5_auth_con_free(Z_krb5_ctx, authctx);
|
||||
}
|
||||
if (!result || result == KRB5KRB_AP_ERR_TKT_EXPIRED) {
|
||||
notice->z_auth = 1;
|
||||
if (result == 0) {
|
||||
notice->z_authent_len = authent->length;
|
||||
} else {
|
||||
notice->z_authent_len = 0;
|
||||
result = 0;
|
||||
}
|
||||
zcode_len = notice->z_authent_len * 2 + 2; /* 2x growth plus Z and null */
|
||||
notice->z_ascii_authent = (char *)malloc(zcode_len);
|
||||
if (notice->z_ascii_authent == NULL)
|
||||
result = ENOMEM;
|
||||
}
|
||||
if (!result)
|
||||
result = ZMakeZcode(notice->z_ascii_authent, zcode_len,
|
||||
(unsigned char *)authent->data, notice->z_authent_len);
|
||||
|
||||
/* format the notice header, with a zero checksum */
|
||||
if (!result)
|
||||
result = Z_NewFormatRawHeader(notice, buffer, buffer_len, phdr_len,
|
||||
&cksum_start, &cksum_len, &cstart, &cend);
|
||||
notice->z_authent_len = 0;
|
||||
if (!result)
|
||||
result = Z_InsertZcodeChecksum(keyblock, notice, buffer, cksum_start,
|
||||
cksum_len, cstart, cend, buffer_len,
|
||||
&phdr_adj, 0);
|
||||
if (!result)
|
||||
*phdr_len += phdr_adj;
|
||||
|
||||
if (notice->z_ascii_authent != NULL)
|
||||
free(notice->z_ascii_authent);
|
||||
krb5_free_data_contents(Z_krb5_ctx, authent);
|
||||
if (authent != NULL)
|
||||
free(authent);
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
ZGetCreds(krb5_creds **creds_out)
|
||||
{
|
||||
return ZGetCredsRealm(creds_out, __Zephyr_realm);
|
||||
}
|
||||
|
||||
int
|
||||
ZGetCredsRealm(krb5_creds **creds_out,
|
||||
char *realm)
|
||||
{
|
||||
krb5_creds creds_in;
|
||||
krb5_creds creds_tmp;
|
||||
krb5_ccache ccache; /* XXX make this a global or static?*/
|
||||
int result;
|
||||
|
||||
result = krb5_cc_default(Z_krb5_ctx, &ccache);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
memset((char *)&creds_in, 0, sizeof(creds_in));
|
||||
result = krb5_build_principal(Z_krb5_ctx, &creds_in.server,
|
||||
strlen(realm),
|
||||
realm,
|
||||
SERVER_SERVICE, SERVER_INSTANCE,
|
||||
NULL);
|
||||
if (result) {
|
||||
krb5_cc_close(Z_krb5_ctx, ccache);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = krb5_cc_get_principal(Z_krb5_ctx, ccache, &creds_in.client);
|
||||
if (!result) {
|
||||
result = krb5_cc_retrieve_cred(Z_krb5_ctx, ccache,
|
||||
#ifdef KRB5_TC_SUPPORTED_KTYPES
|
||||
KRB5_TC_SUPPORTED_KTYPES, /* MIT */
|
||||
#else
|
||||
0, /* Heimdal or other Space KRB5 */
|
||||
#endif
|
||||
&creds_in, &creds_tmp);
|
||||
if (!result) {
|
||||
*creds_out = malloc(sizeof(creds_tmp));
|
||||
if (*creds_out == NULL)
|
||||
result = errno;
|
||||
else
|
||||
memcpy(*creds_out, &creds_tmp, sizeof(creds_tmp));
|
||||
}
|
||||
}
|
||||
if (result == KRB5_CC_NOTFOUND || result == KRB5_CC_END)
|
||||
result = krb5_get_credentials(Z_krb5_ctx, 0, ccache, &creds_in, creds_out);
|
||||
|
||||
krb5_cc_close(Z_krb5_ctx, ccache);
|
||||
krb5_free_cred_contents(Z_krb5_ctx, &creds_in); /* I also hope this is ok */
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
49
lib/ZNewLocU.c
Normal file
49
lib/ZNewLocU.c
Normal file
@ -0,0 +1,49 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZNewLocateUser function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987,1988,1991 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZNewLocateUser_c[] =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
Code_t
|
||||
ZLocateUser(char *user,
|
||||
int *nlocs,
|
||||
Z_AuthProc auth)
|
||||
{
|
||||
Code_t retval;
|
||||
ZNotice_t notice;
|
||||
ZAsyncLocateData_t zald;
|
||||
|
||||
(void) ZFlushLocations(); /* ZFlushLocations never fails (the library
|
||||
is allowed to know this). */
|
||||
|
||||
if ((retval = ZRequestLocations(user, &zald, UNACKED, auth)) != ZERR_NONE)
|
||||
return(retval);
|
||||
|
||||
retval = Z_WaitForNotice (¬ice, ZCompareALDPred, &zald, SRV_TIMEOUT);
|
||||
if (retval == ZERR_NONOTICE)
|
||||
return ETIMEDOUT;
|
||||
if (retval != ZERR_NONE)
|
||||
return retval;
|
||||
|
||||
if ((retval = ZParseLocations(¬ice, &zald, nlocs, NULL)) != ZERR_NONE) {
|
||||
ZFreeNotice(¬ice);
|
||||
return(retval);
|
||||
}
|
||||
|
||||
ZFreeNotice(¬ice);
|
||||
ZFreeALD(&zald);
|
||||
return(ZERR_NONE);
|
||||
}
|
73
lib/ZOpenPort.c
Normal file
73
lib/ZOpenPort.c
Normal file
@ -0,0 +1,73 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZOpenPort function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZOpenPort_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
Code_t
|
||||
ZOpenPort(u_short *port)
|
||||
{
|
||||
struct sockaddr_in bindin;
|
||||
unsigned int len;
|
||||
int val = 1;
|
||||
|
||||
(void) ZClosePort();
|
||||
|
||||
if ((__Zephyr_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
__Zephyr_fd = -1;
|
||||
return errno;
|
||||
}
|
||||
|
||||
bindin.sin_family = AF_INET;
|
||||
|
||||
if (port && *port) {
|
||||
bindin.sin_port = *port;
|
||||
if (setsockopt(__Zephyr_fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof val) < 0)
|
||||
return errno;
|
||||
} else {
|
||||
bindin.sin_port = 0;
|
||||
}
|
||||
|
||||
bindin.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
if (bind(__Zephyr_fd, (struct sockaddr *)&bindin, sizeof(bindin)) < 0) {
|
||||
if (errno == EADDRINUSE && port && *port)
|
||||
return ZERR_PORTINUSE;
|
||||
else
|
||||
return errno;
|
||||
}
|
||||
|
||||
if (port && *port) {
|
||||
/* turn SO_REUSEADDR back off so no one else can steal it */
|
||||
val = 0;
|
||||
if (setsockopt(__Zephyr_fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof val) < 0)
|
||||
return errno;
|
||||
}
|
||||
|
||||
if (!bindin.sin_port) {
|
||||
len = sizeof(bindin);
|
||||
if (getsockname(__Zephyr_fd, (struct sockaddr *)&bindin, &len))
|
||||
return errno;
|
||||
}
|
||||
|
||||
__Zephyr_port = bindin.sin_port;
|
||||
__Zephyr_open = 1;
|
||||
|
||||
if (port)
|
||||
*port = bindin.sin_port;
|
||||
|
||||
return ZERR_NONE;
|
||||
}
|
315
lib/ZParseNot.c
Normal file
315
lib/ZParseNot.c
Normal file
@ -0,0 +1,315 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZParseNotice function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987,1991 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZParseNotice_c[] =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
#include <syslog.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
inline static int
|
||||
_bad_packet(int line, char *where, ZNotice_t *notice, char *what) {
|
||||
if (__Zephyr_server) {
|
||||
syslog(LOG_ERR, "ZParseNotice: bad packet (%s) from %s.%d at line %d",
|
||||
what, inet_ntoa(notice->z_uid.zuid_addr), notice->z_port, line);
|
||||
} else {
|
||||
#ifdef Z_DEBUG
|
||||
Z_debug("ZParseNotice: bad packet (%s) from %s.%d at line %d",
|
||||
what, inet_ntoa(notice->z_uid.zuid_addr), notice->z_port, line);
|
||||
#endif
|
||||
}
|
||||
|
||||
return ZERR_BADPKT;
|
||||
}
|
||||
|
||||
/* Skip to the next NUL-terminated field in the packet. */
|
||||
inline static char *
|
||||
next_field(char *ptr,
|
||||
char *end)
|
||||
{
|
||||
while (ptr < end && *ptr != '\0')
|
||||
ptr++;
|
||||
if (ptr < end)
|
||||
ptr++;
|
||||
return (ptr);
|
||||
}
|
||||
|
||||
Code_t
|
||||
ZParseNotice(char *buffer,
|
||||
int len,
|
||||
ZNotice_t *notice)
|
||||
{
|
||||
char *ptr, *end;
|
||||
unsigned long temp;
|
||||
int maj, numfields, i;
|
||||
|
||||
#ifndef __LINE__
|
||||
#define __LINE__ -1
|
||||
#endif
|
||||
#define BAD_PACKET(what) return _bad_packet(__LINE__, ptr, notice, what)
|
||||
|
||||
(void) memset((char *)notice, 0, sizeof(ZNotice_t));
|
||||
|
||||
ptr = buffer;
|
||||
end = buffer+len;
|
||||
|
||||
notice->z_packet = buffer;
|
||||
|
||||
notice->z_version = ptr;
|
||||
if (strncmp(ptr, ZVERSIONHDR, sizeof(ZVERSIONHDR) - 1))
|
||||
return (ZERR_VERS);
|
||||
ptr += sizeof(ZVERSIONHDR) - 1;
|
||||
if (!*ptr)
|
||||
BAD_PACKET("null version string");
|
||||
|
||||
maj = atoi(ptr);
|
||||
if (maj != ZVERSIONMAJOR)
|
||||
return (ZERR_VERS);
|
||||
ptr = next_field(ptr, end);
|
||||
|
||||
if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
|
||||
BAD_PACKET("parsing num_hdr_fields");
|
||||
numfields = temp;
|
||||
notice->z_num_hdr_fields = numfields;
|
||||
ptr = next_field(ptr, end);
|
||||
|
||||
/*XXX 3 */
|
||||
numfields -= 2; /* numfields, version, and checksum */
|
||||
if (numfields < 0)
|
||||
BAD_PACKET("no header fields");
|
||||
|
||||
if (numfields && ptr < end) {
|
||||
if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
|
||||
BAD_PACKET("parsing kind");
|
||||
notice->z_kind = (ZNotice_Kind_t)temp;
|
||||
numfields--;
|
||||
ptr = next_field(ptr, end);
|
||||
}
|
||||
else
|
||||
BAD_PACKET("missing kind");
|
||||
|
||||
if (numfields && ptr < end) {
|
||||
if (ZReadAscii(ptr, end-ptr, (unsigned char *)¬ice->z_uid,
|
||||
sizeof(ZUnique_Id_t)) == ZERR_BADFIELD)
|
||||
BAD_PACKET("parsing uid");
|
||||
notice->z_time.tv_sec = ntohl((u_long) notice->z_uid.tv.tv_sec);
|
||||
notice->z_time.tv_usec = ntohl((u_long) notice->z_uid.tv.tv_usec);
|
||||
numfields--;
|
||||
ptr = next_field(ptr, end);
|
||||
}
|
||||
else
|
||||
BAD_PACKET("missing uid");
|
||||
|
||||
if (numfields && ptr < end) {
|
||||
if (ZReadAscii16(ptr, end-ptr, ¬ice->z_port) == ZERR_BADFIELD)
|
||||
BAD_PACKET("parsing port");
|
||||
notice->z_port = htons(notice->z_port);
|
||||
numfields--;
|
||||
ptr = next_field(ptr, end);
|
||||
}
|
||||
else
|
||||
BAD_PACKET("missing port");
|
||||
|
||||
if (numfields && ptr < end) {
|
||||
if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
|
||||
BAD_PACKET("parsing auth");
|
||||
notice->z_auth = temp;
|
||||
numfields--;
|
||||
ptr = next_field(ptr, end);
|
||||
}
|
||||
else
|
||||
BAD_PACKET("missing auth");
|
||||
notice->z_checked_auth = ZAUTH_UNSET;
|
||||
|
||||
if (numfields && ptr < end) {
|
||||
if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
|
||||
BAD_PACKET("parsing authenticator length");
|
||||
notice->z_authent_len = temp;
|
||||
numfields--;
|
||||
ptr = next_field(ptr, end);
|
||||
}
|
||||
else
|
||||
BAD_PACKET("missing authenticator length");
|
||||
|
||||
if (numfields && ptr < end) {
|
||||
notice->z_ascii_authent = ptr;
|
||||
numfields--;
|
||||
ptr = next_field(ptr, end);
|
||||
}
|
||||
else
|
||||
BAD_PACKET("missing authenticator field");
|
||||
|
||||
if (numfields && ptr < end) {
|
||||
notice->z_class = ptr;
|
||||
numfields--;
|
||||
ptr = next_field(ptr, end);
|
||||
}
|
||||
else
|
||||
notice->z_class = "";
|
||||
|
||||
if (numfields && ptr < end) {
|
||||
notice->z_class_inst = ptr;
|
||||
numfields--;
|
||||
ptr = next_field(ptr, end);
|
||||
}
|
||||
else
|
||||
notice->z_class_inst = "";
|
||||
|
||||
if (numfields && ptr < end) {
|
||||
notice->z_opcode = ptr;
|
||||
numfields--;
|
||||
ptr = next_field(ptr, end);
|
||||
}
|
||||
else
|
||||
notice->z_opcode = "";
|
||||
|
||||
if (numfields && ptr < end) {
|
||||
notice->z_sender = ptr;
|
||||
numfields--;
|
||||
ptr = next_field(ptr, end);
|
||||
}
|
||||
else
|
||||
notice->z_sender = "";
|
||||
|
||||
if (numfields && ptr < end) {
|
||||
notice->z_recipient = ptr;
|
||||
numfields--;
|
||||
ptr = next_field(ptr, end);
|
||||
}
|
||||
else
|
||||
notice->z_recipient = "";
|
||||
|
||||
if (numfields && ptr < end) {
|
||||
notice->z_default_format = ptr;
|
||||
numfields--;
|
||||
ptr = next_field(ptr, end);
|
||||
}
|
||||
else
|
||||
notice->z_default_format = "";
|
||||
|
||||
if (numfields && ptr < end) {
|
||||
notice->z_ascii_checksum = ptr;
|
||||
|
||||
if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
|
||||
notice->z_checksum = 0;
|
||||
else
|
||||
notice->z_checksum = temp;
|
||||
|
||||
numfields--;
|
||||
ptr = next_field (ptr, end);
|
||||
}
|
||||
else
|
||||
{
|
||||
notice->z_ascii_checksum = "";
|
||||
notice->z_checksum = 0;
|
||||
}
|
||||
|
||||
if (numfields && ptr < end) {
|
||||
notice->z_multinotice = ptr;
|
||||
numfields--;
|
||||
ptr = next_field(ptr, end);
|
||||
}
|
||||
else
|
||||
notice->z_multinotice = "";
|
||||
|
||||
if (numfields && ptr < end) {
|
||||
if (ZReadAscii(ptr, end-ptr, (unsigned char *)¬ice->z_multiuid,
|
||||
sizeof(ZUnique_Id_t)) == ZERR_BADFIELD)
|
||||
BAD_PACKET("parsing multiuid");
|
||||
notice->z_time.tv_sec = ntohl((u_long) notice->z_multiuid.tv.tv_sec);
|
||||
notice->z_time.tv_usec = ntohl((u_long) notice->z_multiuid.tv.tv_usec);
|
||||
numfields--;
|
||||
ptr = next_field(ptr, end);
|
||||
}
|
||||
else
|
||||
notice->z_multiuid = notice->z_uid;
|
||||
|
||||
if (numfields && ptr < end) {
|
||||
/* we will take it on faith that ipv6 addresses are longer than ipv4
|
||||
addresses */
|
||||
unsigned char addrbuf[sizeof(notice->z_sender_sockaddr.ip6.sin6_addr)];
|
||||
int alen;
|
||||
|
||||
/* because we're paranoid about naughtily misformatted packets */
|
||||
if (memchr(ptr, '\0', end - ptr) == NULL)
|
||||
BAD_PACKET("unterminated address field");
|
||||
|
||||
if (*ptr == 'Z') {
|
||||
if (ZReadZcode((unsigned char *)ptr, addrbuf,
|
||||
sizeof(addrbuf), &alen) == ZERR_BADFIELD)
|
||||
BAD_PACKET("parsing Zcode address");
|
||||
} else {
|
||||
alen = sizeof(notice->z_sender_sockaddr.ip4.sin_addr);
|
||||
if (ZReadAscii(ptr, end - ptr, (unsigned char *)addrbuf,
|
||||
alen) == ZERR_BADFIELD)
|
||||
BAD_PACKET("parsing NetASCII address");
|
||||
}
|
||||
|
||||
if (alen == sizeof(notice->z_sender_sockaddr.ip6.sin6_addr)) {
|
||||
notice->z_sender_sockaddr.ip6.sin6_family = AF_INET6;
|
||||
memcpy(¬ice->z_sender_sockaddr.ip6.sin6_addr, addrbuf, alen);
|
||||
#ifdef HAVE_SOCKADDR_IN6_SIN6_LEN
|
||||
notice->z_sender_sockaddr.ip6.sin6_len = sizeof(notice->z_sender_sockaddr.ip6);
|
||||
#endif
|
||||
} else if (alen == sizeof(notice->z_sender_sockaddr.ip4.sin_addr)) {
|
||||
notice->z_sender_sockaddr.ip4.sin_family = AF_INET;
|
||||
memcpy(¬ice->z_sender_sockaddr.ip4.sin_addr, addrbuf, alen);
|
||||
#ifdef HAVE_SOCKADDR_IN_SIN_LEN
|
||||
notice->z_sender_sockaddr.ip4.sin_len = sizeof(notice->z_sender_sockaddr.ip4);
|
||||
#endif
|
||||
} else
|
||||
BAD_PACKET("address claims to be neither IPv4 or IPv6");
|
||||
|
||||
numfields--;
|
||||
ptr = next_field(ptr, end);
|
||||
} else {
|
||||
memset(¬ice->z_sender_sockaddr, 0,
|
||||
sizeof notice->z_sender_sockaddr);
|
||||
notice->z_sender_sockaddr.ip4.sin_family = AF_INET;
|
||||
notice->z_sender_sockaddr.ip4.sin_addr = notice->z_uid.zuid_addr;
|
||||
#ifdef HAVE_SOCKADDR_IN_SIN_LEN
|
||||
notice->z_sender_sockaddr.ip4.sin_len = sizeof(notice->z_sender_sockaddr.ip4);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (numfields && ptr < end) {
|
||||
if (ZReadAscii16(ptr, end-ptr, ¬ice->z_charset) == ZERR_BADFIELD)
|
||||
BAD_PACKET("parsing charset");
|
||||
notice->z_charset = htons(notice->z_charset);
|
||||
|
||||
numfields--;
|
||||
ptr = next_field(ptr, end);
|
||||
} else
|
||||
notice->z_charset = ZCHARSET_UNKNOWN;
|
||||
|
||||
for (i=0;ptr < end && i<Z_MAXOTHERFIELDS && numfields;i++,numfields--) {
|
||||
notice->z_other_fields[i] = ptr;
|
||||
ptr = next_field(ptr, end);
|
||||
}
|
||||
notice->z_num_other_fields = i;
|
||||
|
||||
for (i=0;ptr < end && numfields;numfields--)
|
||||
ptr = next_field(ptr, end);
|
||||
|
||||
if (numfields || *(ptr - 1) != '\0')
|
||||
BAD_PACKET("end of headers");
|
||||
|
||||
notice->z_message = (void *)ptr;
|
||||
notice->z_message_len = len-(ptr-buffer);
|
||||
|
||||
return (ZERR_NONE);
|
||||
}
|
57
lib/ZPeekIfNot.c
Normal file
57
lib/ZPeekIfNot.c
Normal file
@ -0,0 +1,57 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZPeekIfNotice function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZPeekIfNotice_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
Code_t
|
||||
ZPeekIfNotice(ZNotice_t *notice,
|
||||
struct sockaddr_in *from,
|
||||
int (*predicate)(ZNotice_t *, char *),
|
||||
char *args)
|
||||
{
|
||||
ZNotice_t tmpnotice;
|
||||
Code_t retval;
|
||||
char *buffer;
|
||||
struct _Z_InputQ *qptr;
|
||||
|
||||
if ((retval = Z_WaitForComplete()) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
for (;;) {
|
||||
qptr = Z_GetFirstComplete();
|
||||
while (qptr) {
|
||||
if ((retval = ZParseNotice(qptr->packet, qptr->packet_len,
|
||||
&tmpnotice)) != ZERR_NONE)
|
||||
return (retval);
|
||||
if ((*predicate)(&tmpnotice, args)) {
|
||||
if (!(buffer = (char *) malloc((unsigned) qptr->packet_len)))
|
||||
return (ENOMEM);
|
||||
(void) memcpy(buffer, qptr->packet, qptr->packet_len);
|
||||
if (from)
|
||||
*from = qptr->from;
|
||||
if ((retval = ZParseNotice(buffer, qptr->packet_len,
|
||||
notice)) != ZERR_NONE) {
|
||||
free(buffer);
|
||||
return (retval);
|
||||
}
|
||||
return (ZERR_NONE);
|
||||
}
|
||||
qptr = Z_GetNextComplete(qptr);
|
||||
}
|
||||
if ((retval = Z_ReadWait()) != ZERR_NONE)
|
||||
return (retval);
|
||||
}
|
||||
}
|
31
lib/ZPeekNot.c
Normal file
31
lib/ZPeekNot.c
Normal file
@ -0,0 +1,31 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for ZPeekNotice function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZPeekNotice_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
Code_t
|
||||
ZPeekNotice(ZNotice_t *notice,
|
||||
struct sockaddr_in *from)
|
||||
{
|
||||
char *buffer;
|
||||
int len;
|
||||
Code_t retval;
|
||||
|
||||
if ((retval = ZPeekPacket(&buffer, &len, from)) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
return (ZParseNotice(buffer, len, notice));
|
||||
}
|
43
lib/ZPeekPkt.c
Normal file
43
lib/ZPeekPkt.c
Normal file
@ -0,0 +1,43 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for ZPeekPacket function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZPeekPacket_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
Code_t
|
||||
ZPeekPacket(char **buffer,
|
||||
int *ret_len,
|
||||
struct sockaddr_in *from)
|
||||
{
|
||||
Code_t retval;
|
||||
struct _Z_InputQ *nextq;
|
||||
|
||||
if ((retval = Z_WaitForComplete()) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
nextq =Z_GetFirstComplete();
|
||||
|
||||
*ret_len = nextq->packet_len;
|
||||
|
||||
if (!(*buffer = (char *) malloc((unsigned) *ret_len)))
|
||||
return (ENOMEM);
|
||||
|
||||
(void) memcpy(*buffer, nextq->packet, *ret_len);
|
||||
|
||||
if (from)
|
||||
*from = nextq->from;
|
||||
|
||||
return (ZERR_NONE);
|
||||
}
|
35
lib/ZPending.c
Normal file
35
lib/ZPending.c
Normal file
@ -0,0 +1,35 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZPending function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZPending_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
int
|
||||
ZPending(void)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (ZGetFD() < 0) {
|
||||
errno = ZERR_NOPORT;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if ((retval = Z_ReadEnqueue()) != ZERR_NONE) {
|
||||
errno = retval;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return(ZQLength());
|
||||
}
|
88
lib/ZReadAscii.c
Normal file
88
lib/ZReadAscii.c
Normal file
@ -0,0 +1,88 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZReadAscii function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987, 1990 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZReadAscii_c[] = "$Id$";
|
||||
#endif /* lint */
|
||||
|
||||
#include <internal.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define Z_cnvt_xtoi(c) ((temp=(c)-'0'),(temp<10)?temp:((temp-='A'-'9'-1),(temp<16)?temp:-1))
|
||||
|
||||
Code_t
|
||||
ZReadAscii(char *ptr,
|
||||
int len,
|
||||
unsigned char *field,
|
||||
int num)
|
||||
{
|
||||
int i;
|
||||
unsigned int hexbyte;
|
||||
register int c1, c2;
|
||||
register int temp;
|
||||
|
||||
for (i=0;i<num;i++) {
|
||||
if (len >= 1 && *ptr == ' ') {
|
||||
ptr++;
|
||||
len--;
|
||||
}
|
||||
if (len >= 2 && ptr[0] == '0' && ptr[1] == 'x') {
|
||||
ptr += 2;
|
||||
len -= 2;
|
||||
}
|
||||
if (len < 2)
|
||||
return ZERR_BADFIELD;
|
||||
c1 = Z_cnvt_xtoi(ptr[0]);
|
||||
if (c1 < 0)
|
||||
return ZERR_BADFIELD;
|
||||
c2 = Z_cnvt_xtoi(ptr[1]);
|
||||
if (c2 < 0)
|
||||
return ZERR_BADFIELD;
|
||||
hexbyte = (c1 << 4) | c2;
|
||||
field[i] = hexbyte;
|
||||
ptr += 2;
|
||||
len -= 2;
|
||||
}
|
||||
|
||||
return *ptr ? ZERR_BADFIELD : ZERR_NONE;
|
||||
}
|
||||
|
||||
Code_t
|
||||
ZReadAscii32(char *ptr,
|
||||
int len,
|
||||
unsigned long *value_ptr)
|
||||
{
|
||||
unsigned char buf[4];
|
||||
Code_t retval;
|
||||
|
||||
retval = ZReadAscii(ptr, len, buf, 4);
|
||||
if (retval != ZERR_NONE)
|
||||
return retval;
|
||||
*value_ptr = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
|
||||
return ZERR_NONE;
|
||||
}
|
||||
|
||||
Code_t
|
||||
ZReadAscii16(char *ptr,
|
||||
int len,
|
||||
unsigned short *value_ptr)
|
||||
{
|
||||
unsigned char buf[2];
|
||||
Code_t retval;
|
||||
|
||||
retval = ZReadAscii(ptr, len, buf, 2);
|
||||
if (retval != ZERR_NONE)
|
||||
return retval;
|
||||
*value_ptr = (buf[0] << 8) | buf[1];
|
||||
return ZERR_NONE;
|
||||
}
|
||||
|
48
lib/ZReadZcode.c
Normal file
48
lib/ZReadZcode.c
Normal file
@ -0,0 +1,48 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZReadZcode function.
|
||||
*
|
||||
* Created by: Jeffrey Hutzelman
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987, 1990, 2002 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZReadZcode_c[] = "$Id$";
|
||||
#endif /* lint */
|
||||
|
||||
#include <internal.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
Code_t
|
||||
ZReadZcode(unsigned char *ptr,
|
||||
unsigned char *field,
|
||||
int max,
|
||||
int *len)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
if (*ptr++ != 'Z')
|
||||
return ZERR_BADFIELD;
|
||||
|
||||
while (*ptr && n < max) {
|
||||
if (*ptr == 0xff) {
|
||||
ptr++;
|
||||
switch (*ptr++) {
|
||||
case 0xf0: field[n++] = 0x00; continue;
|
||||
case 0xf1: field[n++] = 0xff; continue;
|
||||
default: return ZERR_BADFIELD;
|
||||
}
|
||||
} else {
|
||||
field[n++] = *ptr++;
|
||||
}
|
||||
}
|
||||
if (*ptr)
|
||||
return (ZERR_BADFIELD);
|
||||
*len = n;
|
||||
return (ZERR_NONE);
|
||||
}
|
52
lib/ZRecvNot.c
Normal file
52
lib/ZRecvNot.c
Normal file
@ -0,0 +1,52 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for ZReceiveNotice function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZReceiveNotice_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
Code_t
|
||||
ZReceiveNotice(ZNotice_t *notice,
|
||||
struct sockaddr_in *from)
|
||||
{
|
||||
char *buffer;
|
||||
struct _Z_InputQ *nextq;
|
||||
int len, auth;
|
||||
Code_t retval;
|
||||
|
||||
if ((retval = Z_WaitForComplete()) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
nextq = Z_GetFirstComplete();
|
||||
if (!nextq)
|
||||
return (ENOMEM);
|
||||
|
||||
len = nextq->packet_len;
|
||||
|
||||
if (!(buffer = (char *) malloc((unsigned) len)))
|
||||
return (ENOMEM);
|
||||
|
||||
if (from)
|
||||
*from = nextq->from;
|
||||
|
||||
(void) memcpy(buffer, nextq->packet, len);
|
||||
|
||||
auth = nextq->auth;
|
||||
Z_RemQueue(nextq);
|
||||
|
||||
if ((retval = ZParseNotice(buffer, len, notice)) != ZERR_NONE)
|
||||
return (retval);
|
||||
notice->z_checked_auth = auth;
|
||||
return ZERR_NONE;
|
||||
}
|
44
lib/ZRecvPkt.c
Normal file
44
lib/ZRecvPkt.c
Normal file
@ -0,0 +1,44 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for ZReceivePacket function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZReceivePacket_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
Code_t
|
||||
ZReceivePacket(ZPacket_t buffer,
|
||||
int *ret_len,
|
||||
struct sockaddr_in *from)
|
||||
{
|
||||
Code_t retval;
|
||||
struct _Z_InputQ *nextq;
|
||||
|
||||
if ((retval = Z_WaitForComplete()) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
nextq = Z_GetFirstComplete();
|
||||
|
||||
*ret_len = nextq->packet_len;
|
||||
if (*ret_len > Z_MAXPKTLEN)
|
||||
return (ZERR_PKTLEN);
|
||||
|
||||
(void) memcpy(buffer, nextq->packet, *ret_len);
|
||||
|
||||
if (from)
|
||||
*from = nextq->from;
|
||||
|
||||
Z_RemQueue(nextq);
|
||||
|
||||
return (ZERR_NONE);
|
||||
}
|
185
lib/ZRetSubs.c
Normal file
185
lib/ZRetSubs.c
Normal file
@ -0,0 +1,185 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZRetrieveSubscriptions and
|
||||
* ZRetrieveDefaultSubscriptions functions.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987,1988,1991 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZRetrieveSubscriptions_c[] =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
static Code_t Z_RetSubs (register ZNotice_t *, int *, Z_AuthProc);
|
||||
|
||||
/* Need STDC definition when possible for unsigned short argument. */
|
||||
Code_t
|
||||
ZRetrieveSubscriptions(unsigned short port,
|
||||
int *nsubs)
|
||||
{
|
||||
int retval;
|
||||
ZNotice_t notice;
|
||||
char asciiport[50];
|
||||
|
||||
if (!port) /* use default port */
|
||||
port = __Zephyr_port;
|
||||
|
||||
retval = ZMakeAscii16(asciiport, sizeof(asciiport), ntohs(port));
|
||||
if (retval != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
(void) memset((char *)¬ice, 0, sizeof(notice));
|
||||
notice.z_message = asciiport;
|
||||
notice.z_message_len = strlen(asciiport)+1;
|
||||
notice.z_opcode = CLIENT_GIMMESUBS;
|
||||
|
||||
return(Z_RetSubs(¬ice, nsubs, ZAUTH));
|
||||
}
|
||||
|
||||
Code_t
|
||||
ZRetrieveDefaultSubscriptions(int *nsubs)
|
||||
{
|
||||
ZNotice_t notice;
|
||||
|
||||
(void) memset((char *)¬ice, 0, sizeof(notice));
|
||||
notice.z_message = (char *) 0;
|
||||
notice.z_message_len = 0;
|
||||
notice.z_opcode = CLIENT_GIMMEDEFS;
|
||||
|
||||
return(Z_RetSubs(¬ice, nsubs, ZNOAUTH));
|
||||
|
||||
}
|
||||
|
||||
static Code_t
|
||||
Z_RetSubs(register ZNotice_t *notice,
|
||||
int *nsubs,
|
||||
Z_AuthProc auth_routine)
|
||||
{
|
||||
register int i;
|
||||
int retval,nrecv,gimmeack;
|
||||
ZNotice_t retnotice;
|
||||
char *ptr,*end,*ptr2;
|
||||
ZSubscription_t *list = __subscriptions_list;
|
||||
|
||||
retval = ZFlushSubscriptions();
|
||||
|
||||
if (retval != ZERR_NONE && retval != ZERR_NOSUBSCRIPTIONS)
|
||||
return (retval);
|
||||
|
||||
if (ZGetFD() < 0)
|
||||
if ((retval = ZOpenPort((u_short *)0)) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
notice->z_kind = ACKED;
|
||||
notice->z_port = __Zephyr_port;
|
||||
notice->z_class = ZEPHYR_CTL_CLASS;
|
||||
notice->z_class_inst = ZEPHYR_CTL_CLIENT;
|
||||
notice->z_sender = 0;
|
||||
notice->z_recipient = "";
|
||||
notice->z_default_format = "";
|
||||
|
||||
if ((retval = ZSendNotice(notice,auth_routine)) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
nrecv = 0;
|
||||
gimmeack = 0;
|
||||
list = (ZSubscription_t *) 0;
|
||||
|
||||
while (!nrecv || !gimmeack) {
|
||||
retval = Z_WaitForNotice (&retnotice, ZCompareMultiUIDPred,
|
||||
¬ice->z_multiuid, SRV_TIMEOUT);
|
||||
if (retval == ZERR_NONOTICE)
|
||||
return ETIMEDOUT;
|
||||
else if (retval != ZERR_NONE)
|
||||
return retval;
|
||||
|
||||
if (retnotice.z_kind == SERVNAK) {
|
||||
ZFreeNotice(&retnotice);
|
||||
return (ZERR_SERVNAK);
|
||||
}
|
||||
/* non-matching protocol version numbers means the
|
||||
server is probably an older version--must punt */
|
||||
if (strcmp(notice->z_version,retnotice.z_version)) {
|
||||
ZFreeNotice(&retnotice);
|
||||
return(ZERR_VERS);
|
||||
}
|
||||
if (retnotice.z_kind == SERVACK &&
|
||||
!strcmp(retnotice.z_opcode,notice->z_opcode)) {
|
||||
ZFreeNotice(&retnotice);
|
||||
gimmeack = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (retnotice.z_kind != ACKED) {
|
||||
ZFreeNotice(&retnotice);
|
||||
return (ZERR_INTERNAL);
|
||||
}
|
||||
|
||||
nrecv++;
|
||||
|
||||
end = retnotice.z_message+retnotice.z_message_len;
|
||||
|
||||
__subscriptions_num = 0;
|
||||
for (ptr=retnotice.z_message;ptr<end;ptr++)
|
||||
if (!*ptr)
|
||||
__subscriptions_num++;
|
||||
|
||||
__subscriptions_num = __subscriptions_num / 3;
|
||||
|
||||
list = (ZSubscription_t *)
|
||||
malloc(__subscriptions_num * sizeof(ZSubscription_t));
|
||||
if (__subscriptions_num && !list) {
|
||||
ZFreeNotice(&retnotice);
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
ptr = retnotice.z_message;
|
||||
for (i = 0; i < __subscriptions_num; i++) {
|
||||
list[i].zsub_class = (char *)
|
||||
malloc(strlen(ptr) + 1);
|
||||
if (!list[i].zsub_class) {
|
||||
ZFreeNotice(&retnotice);
|
||||
return (ENOMEM);
|
||||
}
|
||||
strcpy(list[i].zsub_class, ptr);
|
||||
ptr += strlen(ptr)+1;
|
||||
list[i].zsub_classinst = (char *)
|
||||
malloc(strlen(ptr) + 1);
|
||||
if (!list[i].zsub_classinst) {
|
||||
ZFreeNotice(&retnotice);
|
||||
return (ENOMEM);
|
||||
}
|
||||
strcpy(list[i].zsub_classinst, ptr);
|
||||
ptr += strlen(ptr)+1;
|
||||
ptr2 = ptr;
|
||||
list[i].zsub_recipient = (char *)
|
||||
malloc(strlen(ptr2) + 2);
|
||||
if (!list[i].zsub_recipient) {
|
||||
ZFreeNotice(&retnotice);
|
||||
return (ENOMEM);
|
||||
}
|
||||
if (*ptr2 == '@' || *ptr2 == 0) {
|
||||
*list[i].zsub_recipient = '*';
|
||||
strcpy(list[i].zsub_recipient + 1, ptr2);
|
||||
} else {
|
||||
strcpy(list[i].zsub_recipient, ptr2);
|
||||
}
|
||||
ptr += strlen(ptr)+1;
|
||||
}
|
||||
ZFreeNotice(&retnotice);
|
||||
}
|
||||
|
||||
__subscriptions_list = list;
|
||||
__subscriptions_next = 0;
|
||||
*nsubs = __subscriptions_num;
|
||||
|
||||
return (ZERR_NONE);
|
||||
}
|
52
lib/ZSendList.c
Normal file
52
lib/ZSendList.c
Normal file
@ -0,0 +1,52 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZSendList function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZSendList_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
Code_t ZSendList(ZNotice_t *notice,
|
||||
char *list[],
|
||||
int nitems,
|
||||
Z_AuthProc cert_routine)
|
||||
{
|
||||
return(ZSrvSendList(notice, list, nitems, cert_routine, Z_XmitFragment));
|
||||
}
|
||||
|
||||
Code_t
|
||||
ZSrvSendList(ZNotice_t *notice,
|
||||
char *list[],
|
||||
int nitems,
|
||||
Z_AuthProc cert_routine,
|
||||
Code_t (*send_routine)(ZNotice_t *, char *, int, int))
|
||||
{
|
||||
Code_t retval;
|
||||
ZNotice_t newnotice;
|
||||
char *buffer;
|
||||
int len;
|
||||
|
||||
if ((retval = ZFormatNoticeList(notice, list, nitems, &buffer,
|
||||
&len, cert_routine)) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
if ((retval = ZParseNotice(buffer, len, &newnotice)) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
retval = Z_SendFragmentedNotice(&newnotice, len, cert_routine,
|
||||
send_routine);
|
||||
|
||||
free(buffer);
|
||||
|
||||
return (retval);
|
||||
}
|
53
lib/ZSendNot.c
Normal file
53
lib/ZSendNot.c
Normal file
@ -0,0 +1,53 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZSendNotice function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZSendNotice_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
Code_t
|
||||
ZSendNotice(ZNotice_t *notice,
|
||||
Z_AuthProc cert_routine)
|
||||
{
|
||||
return(ZSrvSendNotice(notice, cert_routine, Z_XmitFragment));
|
||||
}
|
||||
|
||||
/* Despite its name, this is not used by the server */
|
||||
Code_t
|
||||
ZSrvSendNotice(ZNotice_t *notice,
|
||||
Z_AuthProc cert_routine,
|
||||
Code_t (*send_routine)(ZNotice_t *, char *, int, int))
|
||||
{
|
||||
Code_t retval;
|
||||
ZNotice_t newnotice;
|
||||
char *buffer;
|
||||
int len;
|
||||
|
||||
if ((retval = ZFormatNotice(notice, &buffer, &len,
|
||||
cert_routine)) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
if ((retval = ZParseNotice(buffer, len, &newnotice)) != ZERR_NONE) {
|
||||
free(buffer);
|
||||
return (retval);
|
||||
}
|
||||
|
||||
|
||||
retval = Z_SendFragmentedNotice(&newnotice, len, cert_routine,
|
||||
send_routine);
|
||||
|
||||
free(buffer);
|
||||
|
||||
return (retval);
|
||||
}
|
68
lib/ZSendPkt.c
Normal file
68
lib/ZSendPkt.c
Normal file
@ -0,0 +1,68 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZSendPacket function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987,1991 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZSendPacket_c[] =
|
||||
"$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
static int wait_for_hmack(ZNotice_t *, void *);
|
||||
|
||||
Code_t
|
||||
ZSendPacket(char *packet,
|
||||
int len,
|
||||
int waitforack)
|
||||
{
|
||||
Code_t retval;
|
||||
struct sockaddr_in dest;
|
||||
ZNotice_t notice, acknotice;
|
||||
|
||||
if (!packet || len < 0)
|
||||
return (ZERR_ILLVAL);
|
||||
|
||||
if (len > Z_MAXPKTLEN)
|
||||
return (ZERR_PKTLEN);
|
||||
|
||||
if (ZGetFD() < 0)
|
||||
if ((retval = ZOpenPort((u_short *)0)) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
dest = ZGetDestAddr();
|
||||
|
||||
if (sendto(ZGetFD(), packet, len, 0, (struct sockaddr *)&dest,
|
||||
sizeof(dest)) < 0)
|
||||
return (errno);
|
||||
|
||||
if (!waitforack)
|
||||
return (ZERR_NONE);
|
||||
|
||||
if ((retval = ZParseNotice(packet, len, ¬ice)) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
retval = Z_WaitForNotice(&acknotice, wait_for_hmack, ¬ice.z_uid,
|
||||
HM_TIMEOUT);
|
||||
if (retval == ETIMEDOUT)
|
||||
return ZERR_HMDEAD;
|
||||
if (retval == ZERR_NONE)
|
||||
ZFreeNotice (&acknotice);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int
|
||||
wait_for_hmack(ZNotice_t *notice,
|
||||
void *uid)
|
||||
{
|
||||
return (notice->z_kind == HMACK && ZCompareUID(¬ice->z_uid, (ZUnique_Id_t *)uid));
|
||||
}
|
48
lib/ZSendRLst.c
Normal file
48
lib/ZSendRLst.c
Normal file
@ -0,0 +1,48 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZSendRawNotice function.
|
||||
*
|
||||
* Created by: John T. Kohl
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZSendRawList_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
Code_t ZSendRawList(ZNotice_t *notice,
|
||||
char *list[],
|
||||
int nitems)
|
||||
{
|
||||
return(ZSrvSendRawList(notice, list, nitems, Z_XmitFragment));
|
||||
}
|
||||
|
||||
Code_t ZSrvSendRawList(ZNotice_t *notice,
|
||||
char *list[],
|
||||
int nitems,
|
||||
Code_t (*send_routine)(ZNotice_t *, char *, int, int))
|
||||
{
|
||||
Code_t retval;
|
||||
ZNotice_t newnotice;
|
||||
char *buffer;
|
||||
int len;
|
||||
|
||||
if ((retval = ZFormatRawNoticeList(notice, list, nitems, &buffer,
|
||||
&len)) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
if ((retval = ZParseNotice(buffer, len, &newnotice)) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
retval = Z_SendFragmentedNotice(&newnotice, len, NULL, send_routine);
|
||||
|
||||
free(buffer);
|
||||
|
||||
return (retval);
|
||||
}
|
39
lib/ZSendRaw.c
Normal file
39
lib/ZSendRaw.c
Normal file
@ -0,0 +1,39 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZSendRawNotice function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZSendRawNotice_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
Code_t
|
||||
ZSendRawNotice(ZNotice_t *notice)
|
||||
{
|
||||
Code_t retval;
|
||||
ZNotice_t newnotice;
|
||||
char *buffer;
|
||||
int len;
|
||||
|
||||
if ((retval = ZFormatRawNotice(notice, &buffer, &len)) !=
|
||||
ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
if ((retval = ZParseNotice(buffer, len, &newnotice)) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
retval = Z_SendFragmentedNotice(&newnotice, len, NULL, Z_XmitFragment);
|
||||
|
||||
free(buffer);
|
||||
|
||||
return (retval);
|
||||
}
|
27
lib/ZSetDest.c
Normal file
27
lib/ZSetDest.c
Normal file
@ -0,0 +1,27 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZSetDestAddr function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZSetDestAddr_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
Code_t
|
||||
ZSetDestAddr(struct sockaddr_in *addr)
|
||||
{
|
||||
__HM_addr = *addr;
|
||||
|
||||
__HM_set = 1;
|
||||
|
||||
return (ZERR_NONE);
|
||||
}
|
28
lib/ZSetFD.c
Normal file
28
lib/ZSetFD.c
Normal file
@ -0,0 +1,28 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZSetFD function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZSetFD_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
Code_t
|
||||
ZSetFD(int fd)
|
||||
{
|
||||
(void) ZClosePort();
|
||||
|
||||
__Zephyr_fd = fd;
|
||||
__Zephyr_open = 0;
|
||||
|
||||
return (ZERR_NONE);
|
||||
}
|
25
lib/ZSetSrv.c
Normal file
25
lib/ZSetSrv.c
Normal file
@ -0,0 +1,25 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZSetServerState function.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZSetServerState_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
Code_t
|
||||
ZSetServerState(int state)
|
||||
{
|
||||
__Zephyr_server = state;
|
||||
|
||||
return (ZERR_NONE);
|
||||
}
|
258
lib/ZSubs.c
Normal file
258
lib/ZSubs.c
Normal file
@ -0,0 +1,258 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZSubscribeTo, ZUnsubscribeTo, and
|
||||
* ZCancelSubscriptions functions.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987,1988 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZSubscriptions_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
static Code_t Z_SendAndWaitForServer(ZNotice_t *notice, char *buf, int len,
|
||||
int waitforack);
|
||||
|
||||
#ifdef CMU_ZCTL_PUNT
|
||||
Code_t
|
||||
ZPunt(ZSubscription_t *sublist,
|
||||
int nitems,
|
||||
unsigned int port)
|
||||
{
|
||||
return (ZSubscriptions(sublist, nitems, port, "SUPPRESS",
|
||||
Z_SendAndWaitForServer));
|
||||
}
|
||||
#endif
|
||||
|
||||
Code_t
|
||||
ZSubscribeTo(ZSubscription_t *sublist,
|
||||
int nitems,
|
||||
unsigned int port)
|
||||
{
|
||||
return (ZSubscriptions(sublist, nitems, port, CLIENT_SUBSCRIBE,
|
||||
Z_SendAndWaitForServer));
|
||||
}
|
||||
|
||||
Code_t
|
||||
ZSubscribeToSansDefaults(ZSubscription_t *sublist,
|
||||
int nitems,
|
||||
unsigned int port)
|
||||
{
|
||||
return (ZSubscriptions(sublist, nitems, port, CLIENT_SUBSCRIBE_NODEFS,
|
||||
Z_SendAndWaitForServer));
|
||||
}
|
||||
|
||||
Code_t
|
||||
ZUnsubscribeTo(ZSubscription_t *sublist,
|
||||
int nitems,
|
||||
unsigned int port)
|
||||
{
|
||||
return (ZSubscriptions(sublist, nitems, port, CLIENT_UNSUBSCRIBE,
|
||||
Z_SendAndWaitForServer));
|
||||
}
|
||||
|
||||
Code_t
|
||||
ZCancelSubscriptions(unsigned int port)
|
||||
{
|
||||
return (ZSubscriptions((ZSubscription_t *)0, 0, port, CLIENT_CANCELSUB,
|
||||
Z_SendAndWaitForServer));
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine must do its own fragmentation. Subscriptions must
|
||||
* not be broken across packet boundaries, or else the server will
|
||||
* mis-interpret them.
|
||||
*/
|
||||
|
||||
Code_t
|
||||
ZSubscriptions(register ZSubscription_t *sublist,
|
||||
int nitems,
|
||||
unsigned int port,
|
||||
char *opcode,
|
||||
Code_t (*send_routine)(ZNotice_t *, char *, int, int))
|
||||
{
|
||||
register int i, j;
|
||||
int retval;
|
||||
ZNotice_t notice;
|
||||
char header[Z_MAXHEADERLEN];
|
||||
char **list;
|
||||
char *recip;
|
||||
int hdrlen;
|
||||
/* Space available for data, adjusted below. Take off Z_FRAGFUDGE twice.
|
||||
The first is to account for Z_SendFragmentedNotice's space. The second
|
||||
to account for hdrlen not being constant. Zcode escapes bytes 0x00 and
|
||||
0xFF, so some bytes are encoded as two bytes. */
|
||||
int size_avail = Z_MAXPKTLEN-Z_FRAGFUDGE-Z_FRAGFUDGE;
|
||||
int size, start, numok;
|
||||
Z_AuthProc cert_routine;
|
||||
|
||||
/* nitems = 0 means cancel all subscriptions; still need to allocate a */
|
||||
/* array for one item so we can cancel, however. */
|
||||
|
||||
list = (char **)malloc((unsigned)((nitems==0)?1:nitems)*3*sizeof(char *));
|
||||
if (!list)
|
||||
return (ENOMEM);
|
||||
|
||||
(void) memset((char *)¬ice, 0, sizeof(notice));
|
||||
notice.z_kind = ACKED;
|
||||
notice.z_port = port;
|
||||
notice.z_class = ZEPHYR_CTL_CLASS;
|
||||
notice.z_class_inst = ZEPHYR_CTL_CLIENT;
|
||||
notice.z_opcode = opcode;
|
||||
notice.z_sender = 0;
|
||||
notice.z_recipient = "";
|
||||
notice.z_default_format = "";
|
||||
notice.z_message_len = 0;
|
||||
|
||||
/* format the header to figure out how long it is */
|
||||
retval = Z_FormatHeader(¬ice, header, sizeof(header), &hdrlen, ZAUTH);
|
||||
if (retval != ZERR_NONE) {
|
||||
free((char *)list);
|
||||
return(retval);
|
||||
}
|
||||
|
||||
/* if a subscription request, we save the key */
|
||||
if (strcmp(opcode, CLIENT_SUBSCRIBE) == 0 ||
|
||||
strcmp(opcode, CLIENT_SUBSCRIBE_NODEFS) == 0) {
|
||||
cert_routine = ZSUBAUTH;
|
||||
} else {
|
||||
cert_routine = ZAUTH;
|
||||
}
|
||||
|
||||
/* compute amount of room left */
|
||||
size_avail -= hdrlen;
|
||||
size = size_avail;
|
||||
|
||||
/* assemble subs into an array of pointers */
|
||||
for (i=0;i<nitems;i++) {
|
||||
list[i*3] = sublist[i].zsub_class;
|
||||
list[i*3+1] = sublist[i].zsub_classinst;
|
||||
recip = sublist[i].zsub_recipient;
|
||||
if (recip && *recip == '*')
|
||||
recip++;
|
||||
if (!recip || (*recip != 0 && *recip != '@'))
|
||||
recip = ZGetSender();
|
||||
list[i*3+2] = recip;
|
||||
}
|
||||
|
||||
start = -1;
|
||||
i = 0;
|
||||
numok = 0;
|
||||
if (!nitems) {
|
||||
/* there aren't really any, but we need to xmit anyway */
|
||||
retval = ZSrvSendList(¬ice, list, 0, cert_routine, send_routine);
|
||||
free((char *)list);
|
||||
return(retval);
|
||||
}
|
||||
while(i < nitems) {
|
||||
if (start == -1) {
|
||||
size = size_avail;
|
||||
start = i;
|
||||
numok = 0;
|
||||
}
|
||||
if ((j = strlen(list[i*3])
|
||||
+ strlen(list[i*3+1])
|
||||
+ strlen(list[i*3+2]) + 3) <= size) {
|
||||
/* it will fit in this packet */
|
||||
size -= j;
|
||||
numok++;
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if (!numok) { /* a single subscription won't
|
||||
fit into one packet */
|
||||
free((char *)list);
|
||||
return(ZERR_FIELDLEN);
|
||||
}
|
||||
retval = ZSrvSendList(¬ice, &list[start*3], numok * 3,
|
||||
cert_routine, send_routine);
|
||||
if (retval) {
|
||||
free((char *)list);
|
||||
return(retval);
|
||||
}
|
||||
start = -1;
|
||||
}
|
||||
if (numok)
|
||||
retval = ZSrvSendList(¬ice, &list[start*3], numok * 3,
|
||||
cert_routine, send_routine);
|
||||
free((char *)list);
|
||||
return(retval);
|
||||
}
|
||||
|
||||
static Code_t
|
||||
Z_SendAndWaitForServer(ZNotice_t *notice,
|
||||
char *buf, int len,
|
||||
int waitforack)
|
||||
{
|
||||
Code_t retval;
|
||||
ZNotice_t retnotice;
|
||||
|
||||
retval = ZSendPacket(buf, len, waitforack);
|
||||
if (retval != ZERR_NONE)
|
||||
return (retval);
|
||||
/* Z_ReadWait drops non-initial SERVACKs and SERVNAKs on the floor. We
|
||||
should never see a non-initial one here, but be defensive about bugs in the
|
||||
sharding code above. */
|
||||
if (!ZCompareUID(¬ice->z_multiuid, ¬ice->z_uid))
|
||||
return (retval);
|
||||
if ((retval = ZIfNotice(&retnotice, (struct sockaddr_in *)0,
|
||||
ZCompareUIDPred, (char *)¬ice->z_uid)) !=
|
||||
ZERR_NONE)
|
||||
return (retval);
|
||||
if (retnotice.z_kind == SERVNAK) {
|
||||
ZFreeNotice(&retnotice);
|
||||
return (ZERR_SERVNAK);
|
||||
}
|
||||
if (retnotice.z_kind != SERVACK) {
|
||||
ZFreeNotice(&retnotice);
|
||||
return (ZERR_INTERNAL);
|
||||
}
|
||||
ZFreeNotice(&retnotice);
|
||||
return (ZERR_NONE);
|
||||
}
|
||||
|
||||
Code_t
|
||||
ZFlushUserSubscriptions(char *recip)
|
||||
{
|
||||
register Code_t retval;
|
||||
ZNotice_t notice, retnotice;
|
||||
|
||||
(void)memset((char *)¬ice, 0, sizeof(notice));
|
||||
notice.z_kind = ACKED;
|
||||
notice.z_class = ZEPHYR_CTL_CLASS;
|
||||
notice.z_class_inst = ZEPHYR_CTL_CLIENT;
|
||||
notice.z_opcode = CLIENT_FLUSHSUBS;
|
||||
notice.z_recipient = "";
|
||||
notice.z_default_format = "";
|
||||
if (recip) {
|
||||
notice.z_message = recip;
|
||||
notice.z_message_len = strlen(recip) + 1;
|
||||
} else {
|
||||
notice.z_message_len = 0;
|
||||
}
|
||||
|
||||
if ((retval = ZSendNotice(¬ice, ZAUTH)) != ZERR_NONE)
|
||||
return (retval);
|
||||
|
||||
if ((retval = ZIfNotice(&retnotice, (struct sockaddr_in *)0,
|
||||
ZCompareUIDPred, (char *)¬ice.z_uid)) !=
|
||||
ZERR_NONE)
|
||||
return (retval);
|
||||
if (retnotice.z_kind == SERVNAK) {
|
||||
ZFreeNotice(&retnotice);
|
||||
return (ZERR_SERVNAK);
|
||||
}
|
||||
if (retnotice.z_kind != SERVACK) {
|
||||
ZFreeNotice(&retnotice);
|
||||
return (ZERR_INTERNAL);
|
||||
}
|
||||
ZFreeNotice(&retnotice);
|
||||
return (ZERR_NONE);
|
||||
}
|
195
lib/ZVariables.c
Normal file
195
lib/ZVariables.c
Normal file
@ -0,0 +1,195 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZGetVariable, ZSetVariable, and ZUnsetVariable
|
||||
* functions.
|
||||
*
|
||||
* Created by: Robert French
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1987 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZVariables_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <pwd.h>
|
||||
|
||||
Code_t get_localvarfile(char *bfr);
|
||||
static char *get_varval(char *fn, char *val);
|
||||
static int varline(char *bfr, char *var);
|
||||
|
||||
char *
|
||||
ZGetVariable(char *var)
|
||||
{
|
||||
char varfile[128], *ret;
|
||||
Code_t code;
|
||||
|
||||
code = get_localvarfile(varfile);
|
||||
if (code)
|
||||
return ((char *)0);
|
||||
|
||||
if ((ret = get_varval(varfile, var)) != ZERR_NONE)
|
||||
return (ret);
|
||||
|
||||
sprintf(varfile, "%s/zephyr/zephyr.vars", SYSCONFDIR);
|
||||
return (get_varval(varfile, var));
|
||||
}
|
||||
|
||||
Code_t
|
||||
ZSetVariable(char *var, char *value)
|
||||
{
|
||||
int written;
|
||||
FILE *fpin, *fpout;
|
||||
char varfile[128], varfilebackup[128], varbfr[512];
|
||||
Code_t code;
|
||||
|
||||
written = 0;
|
||||
|
||||
code = get_localvarfile(varfile);
|
||||
if (code)
|
||||
return code;
|
||||
|
||||
(void) strcpy(varfilebackup, varfile);
|
||||
(void) strcat(varfilebackup, ".backup");
|
||||
|
||||
if (!(fpout = fopen(varfilebackup, "w")))
|
||||
return (errno);
|
||||
if ((fpin = fopen(varfile, "r")) != NULL) {
|
||||
while (fgets(varbfr, sizeof varbfr, fpin) != (char *) 0) {
|
||||
if (varbfr[strlen(varbfr)-1] < ' ')
|
||||
varbfr[strlen(varbfr)-1] = '\0';
|
||||
if (varline(varbfr, var)) {
|
||||
fprintf(fpout, "%s = %s\n", var, value);
|
||||
written = 1;
|
||||
}
|
||||
else
|
||||
fprintf(fpout, "%s\n", varbfr);
|
||||
}
|
||||
(void) fclose(fpin); /* don't care about errs on input */
|
||||
}
|
||||
if (!written)
|
||||
fprintf(fpout, "%s = %s\n", var, value);
|
||||
if (fclose(fpout) == EOF)
|
||||
return(EIO); /* can't rely on errno */
|
||||
if (rename(varfilebackup, varfile))
|
||||
return (errno);
|
||||
return (ZERR_NONE);
|
||||
}
|
||||
|
||||
Code_t
|
||||
ZUnsetVariable(char *var)
|
||||
{
|
||||
FILE *fpin, *fpout;
|
||||
char varfile[128], varfilebackup[128], varbfr[512];
|
||||
Code_t code;
|
||||
|
||||
code = get_localvarfile(varfile);
|
||||
if (code)
|
||||
return code;
|
||||
|
||||
(void) strcpy(varfilebackup, varfile);
|
||||
(void) strcat(varfilebackup, ".backup");
|
||||
|
||||
if (!(fpout = fopen(varfilebackup, "w")))
|
||||
return (errno);
|
||||
if ((fpin = fopen(varfile, "r")) != NULL) {
|
||||
while (fgets(varbfr, sizeof varbfr, fpin) != (char *) 0) {
|
||||
if (varbfr[strlen(varbfr)-1] < ' ')
|
||||
varbfr[strlen(varbfr)-1] = '\0';
|
||||
if (!varline(varbfr, var))
|
||||
fprintf(fpout, "%s\n", varbfr);
|
||||
}
|
||||
(void) fclose(fpin); /* don't care about read close errs */
|
||||
}
|
||||
if (fclose(fpout) == EOF)
|
||||
return(EIO); /* errno isn't reliable */
|
||||
if (rename(varfilebackup, varfile))
|
||||
return (errno);
|
||||
return (ZERR_NONE);
|
||||
}
|
||||
|
||||
Code_t
|
||||
get_localvarfile(char *bfr)
|
||||
{
|
||||
char *envptr;
|
||||
struct passwd *pwd;
|
||||
|
||||
envptr = getenv("ZEPHYR_VARS");
|
||||
if (envptr)
|
||||
(void) strcpy(bfr, envptr);
|
||||
else {
|
||||
envptr = getenv("HOME");
|
||||
if (envptr)
|
||||
(void) strcpy(bfr, envptr);
|
||||
else {
|
||||
if (!(pwd = getpwuid((int) getuid())))
|
||||
return errno;
|
||||
(void) strcpy(bfr, pwd->pw_dir);
|
||||
}
|
||||
|
||||
(void) strcat(bfr, "/");
|
||||
(void) strcat(bfr, ".zephyr.vars");
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static char *
|
||||
get_varval(char *fn, char *var)
|
||||
{
|
||||
FILE *fp;
|
||||
static char varbfr[512];
|
||||
int i;
|
||||
|
||||
fp = fopen(fn, "r");
|
||||
if (!fp)
|
||||
return ((char *)0);
|
||||
|
||||
while (fgets(varbfr, sizeof varbfr, fp) != (char *) 0) {
|
||||
if (varbfr[strlen(varbfr)-1] < ' ')
|
||||
varbfr[strlen(varbfr)-1] = '\0';
|
||||
if (!(i = varline(varbfr, var)))
|
||||
continue;
|
||||
(void) fclose(fp); /* open read-only, don't care */
|
||||
return (varbfr+i);
|
||||
}
|
||||
(void) fclose(fp); /* open read-only, don't care */
|
||||
return ((char *)0);
|
||||
}
|
||||
|
||||
/* If the variable in the line bfr[] is the same as var, return index to
|
||||
the variable value, else return 0. */
|
||||
static int
|
||||
varline(char *bfr, char *var)
|
||||
{
|
||||
register char *cp;
|
||||
size_t namelen;
|
||||
|
||||
if (!bfr[0] || bfr[0] == '#') /* comment or null line */
|
||||
return (0);
|
||||
|
||||
cp = bfr;
|
||||
while (*cp && !isspace(*cp) && (*cp != '='))
|
||||
cp++;
|
||||
|
||||
#define max(a,b) ((a > b) ? (a) : (b))
|
||||
|
||||
namelen = cp - bfr;
|
||||
if (strncasecmp(bfr, var, max(strlen(var), namelen)))
|
||||
return(0); /* var is not the var in
|
||||
bfr ==> no match */
|
||||
|
||||
cp = strchr(bfr, '=');
|
||||
if (!cp)
|
||||
return(0);
|
||||
cp++;
|
||||
while (*cp && isspace(*cp)) /* space up to variable value */
|
||||
cp++;
|
||||
|
||||
return (cp - bfr); /* return index */
|
||||
}
|
70
lib/ZWait4Not.c
Normal file
70
lib/ZWait4Not.c
Normal file
@ -0,0 +1,70 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains the ZCheckIfNotice/select loop used for waiting for
|
||||
* a notice, with a timeout.
|
||||
*
|
||||
* Created by: <Joe Random Hacker>
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1991 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#include "mit-copyright.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_ZWaitForNotice_c[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <internal.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
Code_t
|
||||
Z_WaitForNotice(ZNotice_t *notice,
|
||||
int (*pred) __P((ZNotice_t *, void *)),
|
||||
void *arg,
|
||||
int timeout)
|
||||
{
|
||||
Code_t retval;
|
||||
struct timeval tv, t0;
|
||||
fd_set fdmask;
|
||||
int i, fd;
|
||||
|
||||
retval = ZCheckIfNotice (notice, (struct sockaddr_in *) 0, pred,
|
||||
(char *) arg);
|
||||
if (retval == ZERR_NONE)
|
||||
return ZERR_NONE;
|
||||
if (retval != ZERR_NONOTICE)
|
||||
return retval;
|
||||
|
||||
fd = ZGetFD ();
|
||||
FD_ZERO (&fdmask);
|
||||
tv.tv_sec = timeout;
|
||||
tv.tv_usec = 0;
|
||||
gettimeofday (&t0, (struct timezone *) 0);
|
||||
t0.tv_sec += timeout;
|
||||
while (1) {
|
||||
FD_SET (fd, &fdmask);
|
||||
i = select (fd + 1, &fdmask, (fd_set *) 0, (fd_set *) 0, &tv);
|
||||
if (i == 0)
|
||||
return ETIMEDOUT;
|
||||
if (i < 0 && errno != EINTR)
|
||||
return errno;
|
||||
if (i > 0) {
|
||||
retval = ZCheckIfNotice (notice, (struct sockaddr_in *) 0, pred,
|
||||
(char *) arg);
|
||||
if (retval != ZERR_NONOTICE) /* includes ZERR_NONE */
|
||||
return retval;
|
||||
}
|
||||
gettimeofday (&tv, (struct timezone *) 0);
|
||||
tv.tv_usec = t0.tv_usec - tv.tv_usec;
|
||||
if (tv.tv_usec < 0) {
|
||||
tv.tv_usec += 1000000;
|
||||
tv.tv_sec = t0.tv_sec - tv.tv_sec - 1;
|
||||
}
|
||||
else
|
||||
tv.tv_sec = t0.tv_sec - tv.tv_sec;
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
}
|
72
lib/ZhmStat.c
Normal file
72
lib/ZhmStat.c
Normal file
@ -0,0 +1,72 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains the ZhmStat() function.
|
||||
*
|
||||
* Created by: Marc Horowitz
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 1996 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#include <internal.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#ifndef INADDR_LOOPBACK
|
||||
#define INADDR_LOOPBACK 0x7f000001
|
||||
#endif
|
||||
|
||||
Code_t
|
||||
ZhmStat(struct in_addr *hostaddr,
|
||||
ZNotice_t *notice)
|
||||
{
|
||||
struct servent *sp;
|
||||
struct sockaddr_in sin;
|
||||
ZNotice_t req;
|
||||
Code_t code;
|
||||
struct timeval tv;
|
||||
fd_set readers;
|
||||
|
||||
(void) memset((char *)&sin, 0, sizeof(struct sockaddr_in));
|
||||
|
||||
sp = getservbyname(HM_SVCNAME, "udp");
|
||||
|
||||
sin.sin_port = (sp) ? sp->s_port : HM_SVC_FALLBACK;
|
||||
sin.sin_family = AF_INET;
|
||||
|
||||
if (hostaddr)
|
||||
sin.sin_addr = *hostaddr;
|
||||
else
|
||||
sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
|
||||
(void) memset((char *)&req, 0, sizeof(req));
|
||||
req.z_kind = STAT;
|
||||
req.z_port = 0;
|
||||
req.z_class = HM_STAT_CLASS;
|
||||
req.z_class_inst = HM_STAT_CLIENT;
|
||||
req.z_opcode = HM_GIMMESTATS;
|
||||
req.z_sender = "";
|
||||
req.z_recipient = "";
|
||||
req.z_default_format = "";
|
||||
req.z_message_len = 0;
|
||||
|
||||
if ((code = ZSetDestAddr(&sin)) != ZERR_NONE)
|
||||
return(code);
|
||||
|
||||
if ((code = ZSendNotice(&req, ZNOAUTH)) != ZERR_NONE)
|
||||
return(code);
|
||||
|
||||
/* Wait up to ten seconds for a response. */
|
||||
FD_ZERO(&readers);
|
||||
FD_SET(ZGetFD(), &readers);
|
||||
tv.tv_sec = 10;
|
||||
tv.tv_usec = 0;
|
||||
code = select(ZGetFD() + 1, &readers, NULL, NULL, &tv);
|
||||
if (code < 0 && errno != EINTR)
|
||||
return(errno);
|
||||
if (code == 0 || (code < 0 && errno == EINTR) || ZPending() == 0)
|
||||
return(ZERR_HMDEAD);
|
||||
|
||||
return(ZReceiveNotice(notice, (struct sockaddr_in *) 0));
|
||||
}
|
1422
lib/Zinternal.c
Normal file
1422
lib/Zinternal.c
Normal file
File diff suppressed because it is too large
Load Diff
139
lib/charset.c
Normal file
139
lib/charset.c
Normal file
@ -0,0 +1,139 @@
|
||||
/* This file is part of the Project Athena Zephyr Notification System.
|
||||
* It contains source for the ZGetCharset function.
|
||||
*
|
||||
* Created by: Karl Ramm
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (c) 2009 by the Massachusetts Institute of Technology.
|
||||
* For copying and distribution information, see the file
|
||||
* "mit-copyright.h".
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid_charset_c[] = "$Id$";
|
||||
#endif /* lint */
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <locale.h>
|
||||
#include <langinfo.h>
|
||||
#include <ctype.h>
|
||||
#include <iconv.h>
|
||||
#include <errno.h>
|
||||
|
||||
const char *
|
||||
ZGetCharsetString(char *charset)
|
||||
{
|
||||
char *p;
|
||||
static int once = 1;
|
||||
|
||||
if (charset == NULL)
|
||||
charset = getenv("ZEPHYR_CHARSET");
|
||||
|
||||
if (charset == NULL) {
|
||||
if (once) {
|
||||
setlocale(LC_ALL, "");
|
||||
once = 0;
|
||||
}
|
||||
charset = nl_langinfo(CODESET);
|
||||
}
|
||||
|
||||
if (charset == NULL)
|
||||
return ZCHARSET_UNKNOWN;
|
||||
|
||||
charset = strdup(charset);
|
||||
|
||||
for (p = charset; *p; p++)
|
||||
*p = toupper(*p);
|
||||
|
||||
return charset;
|
||||
}
|
||||
|
||||
unsigned short
|
||||
ZGetCharset(char *charset)
|
||||
{
|
||||
short retval;
|
||||
|
||||
charset = (char *)ZGetCharsetString(charset);
|
||||
if (!strcmp(charset, "NONE") || !strcmp(charset, "UNKNOWN"))
|
||||
retval = ZCHARSET_UNKNOWN;
|
||||
else if (!strcmp(charset, "ANSI_X3.4-1968"))
|
||||
retval = ZCHARSET_ISO_8859_1; /* A hack. */
|
||||
else if (!strcmp(charset, "ISO-8859-1"))
|
||||
retval = ZCHARSET_ISO_8859_1;
|
||||
else if (!strcmp(charset, "UTF-8"))
|
||||
retval = ZCHARSET_UTF_8;
|
||||
else
|
||||
retval = ZCHARSET_UNKNOWN;
|
||||
|
||||
free(charset);
|
||||
return retval;
|
||||
}
|
||||
|
||||
const char *
|
||||
ZCharsetToString(unsigned short charset)
|
||||
{
|
||||
if (charset == ZCHARSET_UNKNOWN)
|
||||
return "UNKNOWN";
|
||||
else if (charset == ZCHARSET_ISO_8859_1)
|
||||
return "ISO-8859-1";
|
||||
else if (charset == ZCHARSET_UTF_8)
|
||||
return "UTF-8";
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
Code_t
|
||||
ZTransliterate(char *in, int inlen, char *inset, char *outset, char **out, int *outlen)
|
||||
{
|
||||
iconv_t ih;
|
||||
char *outset_t, *inp, *outp;
|
||||
int retval;
|
||||
size_t size, inleft, outleft;
|
||||
|
||||
*out = NULL;
|
||||
*outlen = 0;
|
||||
|
||||
outset_t = malloc(strlen(outset) + 11);
|
||||
if (outset_t == NULL)
|
||||
return errno;
|
||||
sprintf(outset_t, "%s//TRANSLIT", outset);
|
||||
|
||||
ih = iconv_open(outset_t, inset);
|
||||
|
||||
free(outset_t);
|
||||
|
||||
if (ih == (iconv_t)-1)
|
||||
return errno;
|
||||
|
||||
size = inlen; /* doubling this should be enough, but.. */
|
||||
do {
|
||||
size = size * 2;
|
||||
|
||||
*out = malloc(size);
|
||||
if (*out == NULL) {
|
||||
iconv_close(ih);
|
||||
return errno;
|
||||
}
|
||||
|
||||
inleft = inlen;
|
||||
outleft = size;
|
||||
|
||||
inp = in;
|
||||
outp = *out;
|
||||
|
||||
retval = iconv(ih, &inp, &inleft, &outp, &outleft);
|
||||
if (retval < 0)
|
||||
free(*out);
|
||||
} while (retval < 0 && errno == E2BIG);
|
||||
|
||||
iconv_close(ih);
|
||||
|
||||
if (retval < 0)
|
||||
return errno;
|
||||
|
||||
*outlen = size - outleft;
|
||||
|
||||
return ZERR_NONE;
|
||||
}
|
24
lib/mit-copyright.h
Normal file
24
lib/mit-copyright.h
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
|
||||
Copyright 1987,1988 by the Massachusetts Institute of Technology
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of the Massachusetts
|
||||
Institute of Technology (M.I.T.) not be used in advertising or publicity
|
||||
pertaining to distribution of the software without specific, written
|
||||
prior permission.
|
||||
|
||||
M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
M.I.T. BE LIABLE FOR ANY SPECIAL, 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.
|
||||
|
||||
*/
|
196
lib/quad_cksum.c
Normal file
196
lib/quad_cksum.c
Normal file
@ -0,0 +1,196 @@
|
||||
/* Lifted from the krb5 1.6 source tree and hacked slightly to fit in here
|
||||
Karl Ramm 12/21/08 */
|
||||
/*
|
||||
* lib/des425/quad_cksum.c
|
||||
*
|
||||
* Copyright 1985, 1986, 1987, 1988,1990 by the Massachusetts Institute
|
||||
* of Technology.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Export of this software from the United States of America may
|
||||
* require a specific license from the United States Government.
|
||||
* It is the responsibility of any person or organization contemplating
|
||||
* export to obtain such a license before exporting.
|
||||
*
|
||||
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
|
||||
* distribute this software and its documentation for any purpose and
|
||||
* without fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright notice and
|
||||
* this permission notice appear in supporting documentation, and that
|
||||
* the name of M.I.T. not be used in advertising or publicity pertaining
|
||||
* to distribution of the software without specific, written prior
|
||||
* permission. Furthermore if you modify this software you must label
|
||||
* your software as modified software and not distribute it in such a
|
||||
* fashion that it might be confused with the original M.I.T. software.
|
||||
* M.I.T. makes no representations about the suitability of
|
||||
* this software for any purpose. It is provided "as is" without express
|
||||
* or implied warranty.
|
||||
*
|
||||
*
|
||||
* This routine does not implement:
|
||||
*
|
||||
*
|
||||
* Quadratic Congruential Manipulation Dectection Code
|
||||
*
|
||||
* ref: "Message Authentication"
|
||||
* R.R. Jueneman, S. M. Matyas, C.H. Meyer
|
||||
* IEEE Communications Magazine,
|
||||
* Sept 1985 Vol 23 No 9 p 29-40
|
||||
*
|
||||
* This routine, part of the Athena DES library built for the Kerberos
|
||||
* authentication system, calculates a manipulation detection code for
|
||||
* a message. It is a much faster alternative to the DES-checksum
|
||||
* method. No guarantees are offered for its security.
|
||||
*
|
||||
* Implementation for 4.2bsd
|
||||
* by S.P. Miller Project Athena/MIT
|
||||
*/
|
||||
|
||||
/*
|
||||
* Algorithm (per paper):
|
||||
* define:
|
||||
* message to be composed of n m-bit blocks X1,...,Xn
|
||||
* optional secret seed S in block X1
|
||||
* MDC in block Xn+1
|
||||
* prime modulus N
|
||||
* accumulator Z
|
||||
* initial (secret) value of accumulator C
|
||||
* N, C, and S are known at both ends
|
||||
* C and , optionally, S, are hidden from the end users
|
||||
* then
|
||||
* (read array references as subscripts over time)
|
||||
* Z[0] = c;
|
||||
* for i = 1...n
|
||||
* Z[i] = (Z[i+1] + X[i])**2 modulo N
|
||||
* X[n+1] = Z[n] = MDC
|
||||
*
|
||||
* Then pick
|
||||
* N = 2**31 -1
|
||||
* m = 16
|
||||
* iterate 4 times over plaintext, also use Zn
|
||||
* from iteration j as seed for iteration j+1,
|
||||
* total MDC is then a 128 bit array of the four
|
||||
* Zn;
|
||||
*
|
||||
* return the last Zn and optionally, all
|
||||
* four as output args.
|
||||
*
|
||||
* Modifications:
|
||||
* To inhibit brute force searches of the seed space, this
|
||||
* implementation is modified to have
|
||||
* Z = 64 bit accumulator
|
||||
* C = 64 bit C seed
|
||||
* N = 2**63 - 1
|
||||
* S = S seed is not implemented here
|
||||
* arithmetic is not quite real double integer precision, since we
|
||||
* cant get at the carry or high order results from multiply,
|
||||
* but nontheless is 64 bit arithmetic.
|
||||
*/
|
||||
/*
|
||||
* This code purports to implement the above algorithm, but fails.
|
||||
*
|
||||
* First of all, there was an implicit mod 2**32 being done on the
|
||||
* machines where this was developed because of their word sizes, and
|
||||
* for compabitility this has to be done on machines with 64-bit
|
||||
* words, so we make it explicit.
|
||||
*
|
||||
* Second, in the squaring operation, I really doubt the carry-over
|
||||
* from the low 31-bit half of the accumulator is being done right,
|
||||
* and using a modulus of 0x7fffffff on the low half of the
|
||||
* accumulator seems completely wrong. And I challenge anyone to
|
||||
* explain where the number 83653421 comes from.
|
||||
*
|
||||
* --Ken Raeburn 2001-04-06
|
||||
*/
|
||||
|
||||
|
||||
/* System include files */
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <internal.h>
|
||||
|
||||
/* Definitions for byte swapping */
|
||||
|
||||
/* vax byte order is LSB first. This is not performance critical, and
|
||||
is far more readable this way. */
|
||||
#define four_bytes_vax_to_nets(x) ((((((x[3]<<8)|x[2])<<8)|x[1])<<8)|x[0])
|
||||
#define vaxtohl(x) four_bytes_vax_to_nets(((const unsigned char *)(x)))
|
||||
#define two_bytes_vax_to_nets(x) ((x[1]<<8)|x[0])
|
||||
#define vaxtohs(x) two_bytes_vax_to_nets(((const unsigned char *)(x)))
|
||||
|
||||
/*** Routines ***************************************************** */
|
||||
#ifdef HAVE_KRB5
|
||||
unsigned long
|
||||
z_quad_cksum(const unsigned char *in, /* input block */
|
||||
uint32_t *out, /* optional longer output */
|
||||
long length, /* original length in bytes */
|
||||
int out_count, /* number of iterations */
|
||||
unsigned char *c_seed /* secret seed, 8 bytes */
|
||||
)
|
||||
{
|
||||
|
||||
/*
|
||||
* this routine both returns the low order of the final (last in
|
||||
* time) 32bits of the checksum, and if "out" is not a null
|
||||
* pointer, a longer version, up to entire 32 bytes of the
|
||||
* checksum is written unto the address pointed to.
|
||||
*/
|
||||
|
||||
register uint32_t z;
|
||||
register uint32_t z2;
|
||||
register uint32_t x;
|
||||
register uint32_t x2;
|
||||
const unsigned char *p;
|
||||
register int32_t len;
|
||||
register int i;
|
||||
|
||||
/* use all 8 bytes of seed */
|
||||
|
||||
z = vaxtohl(c_seed);
|
||||
z2 = vaxtohl((const char *)c_seed+4);
|
||||
if (out == NULL)
|
||||
out_count = 1; /* default */
|
||||
|
||||
/* This is repeated n times!! */
|
||||
for (i = 1; i <=4 && i<= out_count; i++) {
|
||||
len = length;
|
||||
p = in;
|
||||
while (len) {
|
||||
/*
|
||||
* X = Z + Input ... sort of. Carry out from low half
|
||||
* isn't done, so we're using all 32 bits of x now.
|
||||
*/
|
||||
if (len > 1) {
|
||||
x = (z + vaxtohs(p));
|
||||
p += 2;
|
||||
len -= 2;
|
||||
}
|
||||
else {
|
||||
x = (z + *(const unsigned char *)p++);
|
||||
len = 0;
|
||||
}
|
||||
x2 = z2;
|
||||
/*
|
||||
* I think this is supposed to be a squaring operation.
|
||||
* What it really is, I haven't figured out yet.
|
||||
*
|
||||
* Explicit mod 2**32 is for backwards compatibility. Why
|
||||
* mod 0x7fffffff and not 0x80000000 on the low half of
|
||||
* the (supposed) accumulator? And where does the number
|
||||
* 83653421 come from??
|
||||
*/
|
||||
z = (((x * x) + (x2 * x2)) & 0xffffffff) % 0x7fffffff;
|
||||
z2 = ((x * (x2+83653421)) & 0xffffffff) % 0x7fffffff; /* modulo */
|
||||
}
|
||||
|
||||
if (out != NULL) {
|
||||
*out++ = z;
|
||||
*out++ = z2;
|
||||
}
|
||||
}
|
||||
/* return final z value as 32 bit version of checksum */
|
||||
return z;
|
||||
}
|
||||
#endif
|
64
lib/smwgc.c
Normal file
64
lib/smwgc.c
Normal file
@ -0,0 +1,64 @@
|
||||
/* Copyright (c) 1988 by the Massachusetts Institute of Technology.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
#include <zephyr/zephyr.h>
|
||||
|
||||
main()
|
||||
{
|
||||
FILE *fp;
|
||||
char buf[512],*ptr;
|
||||
int auth,retval;
|
||||
u_short port;
|
||||
ZNotice_t notice;
|
||||
ZSubscription_t sub;
|
||||
struct sockaddr_in from;
|
||||
|
||||
if ((retval = ZInitialize()) != ZERR_NONE) {
|
||||
com_err("foo",retval,"initing");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
port = 0;
|
||||
if ((retval = ZOpenPort(&port)) != ZERR_NONE) {
|
||||
com_err("foo",retval,"opening port");
|
||||
exit(1);
|
||||
}
|
||||
printf("Using port %d\n",(int)port);
|
||||
sprintf(buf,"/tmp/wg.%d",getuid());
|
||||
fp = fopen(buf,"w");
|
||||
if (!fp) {
|
||||
com_err("foo",errno,"opening file");
|
||||
exit(1);
|
||||
}
|
||||
fprintf(fp,"%d\n",(int)port);
|
||||
fclose(fp);
|
||||
|
||||
printf("All ready...\n");
|
||||
|
||||
sub.class = "MESSAGE";
|
||||
sub.classinst = "PERSONAL";
|
||||
sub.recipient = ZGetSender();
|
||||
|
||||
if ((retval = ZSubscribeTo(&sub,1,port)) != ZERR_NONE) {
|
||||
com_err("foo",retval,"subscribing");
|
||||
exit(1);
|
||||
}
|
||||
for (;;) {
|
||||
if ((retval = ZReceiveNotice(¬ice,&from)) != ZERR_NONE) {
|
||||
com_err("foo",retval,"receiving packet");
|
||||
continue;
|
||||
}
|
||||
auth = ZCheckAuthentication(¬ice,&from);
|
||||
printf("Class = %s Instance = %s Sender = %s\nTime = %s Auth = %d\n",
|
||||
notice.z_class,notice.z_class_inst,notice.z_sender,
|
||||
ctime(¬ice.z_time.tv_sec),auth);
|
||||
printf("Len = %d\n",notice.z_message_len);
|
||||
/* ptr = notice.z_message;
|
||||
for (;ptr<notice.z_message+notice.z_message_len;) {
|
||||
printf("%s\n",ptr);
|
||||
ptr += strlen(ptr)+1;
|
||||
}
|
||||
printf("\n");*/
|
||||
ZFreeNotice(¬ice);
|
||||
}
|
||||
}
|
93
lib/zephyr.1
Normal file
93
lib/zephyr.1
Normal file
@ -0,0 +1,93 @@
|
||||
.\" $Id$
|
||||
.\"
|
||||
.\" Copyright 1987,1988 by the Massachusetts Institute of Technology
|
||||
.\" All rights reserved. The file /usr/include/zephyr/mit-copyright.h
|
||||
.\" specifies the terms and conditions for redistribution.
|
||||
.\"
|
||||
.TH ZEPHYR 1 "July 1, 1988" "MIT Project Athena"
|
||||
.ds ]W MIT Project Athena
|
||||
.SH NAME
|
||||
zephyr \- Zephyr Notification Service
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
Zephyr is a notice transport and delivery system developed at MIT
|
||||
which runs under 4.3BSD Unix.
|
||||
.PP
|
||||
A Notice Transport and Delivery system is a method of getting small
|
||||
quantities of time sensitive information efficiently from one client
|
||||
(or server) on a network to another. The object is to accomplish this
|
||||
with the highest possible fan-out (i.e., client to server ratio) while
|
||||
maintaining both network and server performance. Zephyr is a
|
||||
multi-cast notice transport and delivery system based upon an
|
||||
authenticated datagram protocol. Localized Zephyr servers provide
|
||||
routing, queueing and dispatching services to clients which
|
||||
communicate with them via the Zephyr Client Library. Two special
|
||||
purpose Zephyr clients, the WindowGram client and the HostManager
|
||||
client provide user and client host communication support.
|
||||
.PP
|
||||
.I Zephyrd(8)
|
||||
servers run on designated server machines. These servers maintain a
|
||||
database of subscriptions and locations for every user using Zephyr.
|
||||
The servers stay in contact with one another, and provide a reliable
|
||||
backup system (via duplication) in the event of network failures.
|
||||
.PP
|
||||
Each client machine on the network runs a
|
||||
.I zhm(8)
|
||||
HostManager client program which is the link between the Zephyr
|
||||
servers and the users. User programs send notices to the HostManager,
|
||||
and the HostManager forwards these notices to the nearest server for
|
||||
action. The HostManager is responsible for ensuring that the notices
|
||||
reach a server, and for finding a new one if its server fails to respond.
|
||||
.PP
|
||||
Each user on the network usually runs a WindowGram client program
|
||||
automatically upon login.
|
||||
.I Zwgc(1)
|
||||
displays notices to the user, and handles user
|
||||
responses. Only notices to which the user has subscribed will be sent
|
||||
to the WindowGram client.
|
||||
.PP
|
||||
Subscriptions are handled through the
|
||||
.I zctl(1)
|
||||
program. This program allows the user to add or delete subscriptions
|
||||
from Zephyr, to add the subscriptions to a file, and to perform other
|
||||
miscellaneous functions.
|
||||
.SH SEE ALSO
|
||||
kerberosintro(1)
|
||||
.br
|
||||
zaway(1), zctl(1), zleave(1), zlocate(1), znol(1), zwgc(1),
|
||||
zwrite(1), zmailnotify(1)
|
||||
.br
|
||||
zhm(8), zephyrd(8), zinit(8), zstat(8), zpopnotify(8),
|
||||
zshutdown_notify(8), syslogd(8)
|
||||
.br
|
||||
Project Athena Technical Plan Section E.4.1, `Zephyr Notification
|
||||
Service'
|
||||
.SH AUTHORS
|
||||
.PP
|
||||
.br
|
||||
Tony Della Fera (MIT-Project Athena, DEC),
|
||||
Mark W. Eichin (MIT-Project Athena),
|
||||
Robert S. French (MIT-Project Athena),
|
||||
David C. Jedlinsky (MIT-Project Athena),
|
||||
John T. Kohl (MIT-Project Athena, DEC),
|
||||
William E. Sommerfeld (MIT-Project Athena).
|
||||
.SH RESTRICTIONS
|
||||
Copyright (c) 1987,1988,1989 by the Massachusetts Institute of Technology.
|
||||
All Rights Reserved.
|
||||
.br
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of the Massachusetts
|
||||
Institute of Technology not be used in advertising or publicity
|
||||
pertaining to distribution of the software without specific, written
|
||||
prior permission.
|
||||
.br
|
||||
M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
M.I.T. BE LIABLE FOR ANY SPECIAL, 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.
|
57
lib/zephyr_err.et
Normal file
57
lib/zephyr_err.et
Normal file
@ -0,0 +1,57 @@
|
||||
# Copyright 1987,1988 Massachusetts Institute of Technology
|
||||
#
|
||||
# For copying and distribution information, see the file
|
||||
# "mit-copyright.h".
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
et zeph
|
||||
|
||||
ec ZERR_PKTLEN,
|
||||
"Packet too long or buffer too small"
|
||||
ec ZERR_HEADERLEN,
|
||||
"Notice header too large"
|
||||
ec ZERR_ILLVAL,
|
||||
"Illegal value in notice"
|
||||
ec ZERR_HMPORT,
|
||||
"Can't get host manager port"
|
||||
ec ZERR_PORTINUSE,
|
||||
"Can't assign port"
|
||||
ec ZERR_BADPKT,
|
||||
"Bad packet format"
|
||||
ec ZERR_VERS,
|
||||
"Incompatible version numbers"
|
||||
ec ZERR_NOPORT,
|
||||
"No port opened"
|
||||
ec ZERR_NONOTICE,
|
||||
"No notices match criteria"
|
||||
ec ZERR_QLEN,
|
||||
"Input queue too long"
|
||||
ec ZERR_HMDEAD,
|
||||
"Hostmanager not responding"
|
||||
ec ZERR_INTERNAL,
|
||||
"Internal error"
|
||||
ec ZERR_NOLOCATIONS,
|
||||
"No previous call to ZLocateUser"
|
||||
ec ZERR_NOMORELOCS,
|
||||
"No more locations available"
|
||||
ec ZERR_FIELDLEN,
|
||||
"Field too long for buffer"
|
||||
ec ZERR_BADFIELD,
|
||||
"Improperly formatted field"
|
||||
ec ZERR_SERVNAK,
|
||||
"SERVNAK received"
|
||||
ec ZERR_AUTHFAIL,
|
||||
"Server could not verify authentication"
|
||||
ec ZERR_LOGINFAIL,
|
||||
"Not logged-in"
|
||||
ec ZERR_NOSUBSCRIPTIONS,
|
||||
"No previous call to ZRetrieveSubscriptions"
|
||||
ec ZERR_NOMORESUBSCRIPTIONS,
|
||||
"No more subscriptions available"
|
||||
ec ZERR_TOOMANYSUBS,
|
||||
"Too many subscriptions to transmit"
|
||||
ec ZERR_EOF,
|
||||
"End of file detected during read"
|
||||
|
||||
end
|
12
lib/zephyr_run_doctests
Executable file
12
lib/zephyr_run_doctests
Executable file
@ -0,0 +1,12 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import sys, doctest
|
||||
|
||||
failures, tests = doctest.testfile("zephyr_tests.txt")
|
||||
|
||||
print failures, 'failures out of', tests, 'tests.'
|
||||
if failures:
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
|
187
lib/zephyr_tests.py
Executable file
187
lib/zephyr_tests.py
Executable file
@ -0,0 +1,187 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# zephyr test suite
|
||||
#
|
||||
# Operates on libraries in the build tree. To test purely internal
|
||||
# interfaces, stuff them in a testing library...
|
||||
|
||||
|
||||
"""Test Suite for libzephyr"""
|
||||
|
||||
import optparse
|
||||
import os
|
||||
import socket
|
||||
import ctypes
|
||||
import ctypes.util
|
||||
import time
|
||||
from ctypes import c_int, c_char, POINTER, c_char_p, sizeof
|
||||
|
||||
from zephyr_ctypes import *
|
||||
|
||||
__revision__ = "$Id$"
|
||||
try:
|
||||
__version__ = "%s/%s" % (__revision__.split()[3], __revision__.split()[2])
|
||||
except IndexError:
|
||||
__version__ = "unknown"
|
||||
|
||||
# TODO: pick some real framework later, we're just poking around for now
|
||||
class TestSuite(object):
|
||||
"""test collection and runner"""
|
||||
def __init__(self, **kwargs):
|
||||
for k, v in kwargs.items():
|
||||
setattr(self, k, v)
|
||||
|
||||
def run(self):
|
||||
tests = sorted([testname for testname in dir(self)
|
||||
if testname.startswith("test_")])
|
||||
failures = []
|
||||
for test in tests:
|
||||
try:
|
||||
print "===", "starting", test, "==="
|
||||
getattr(self, test)()
|
||||
print "===", "done", test, "==="
|
||||
except TestFailure, tf:
|
||||
print "===", "FAILED", test, "==="
|
||||
failures.append([test, tf])
|
||||
|
||||
return failures
|
||||
|
||||
|
||||
class TestFailure(Exception):
|
||||
pass
|
||||
|
||||
def py_make_ascii(input):
|
||||
"""reference ZMakeAscii expressed as python..."""
|
||||
hexes = ["%02X" % ord(ch) for ch in input]
|
||||
output = []
|
||||
for i in range(0, len(hexes), 4):
|
||||
output.append("0x" + "".join(hexes[i:i+4]))
|
||||
return " ".join(output)
|
||||
|
||||
def py_make_zcode(input):
|
||||
"""reference ZMakeZcode expressed as python..."""
|
||||
return "Z" + input.replace("\xff", "\xff\xf1").replace("\0", "\xff\xf0")
|
||||
|
||||
def find_libzephyr(builddir='.'):
|
||||
# find the library
|
||||
libzephyr_paths = ['libzephyr.so', 'libzephyr.dylib']
|
||||
libzephyr_paths += [os.path.join('.libs', i) for i in libzephyr_paths]
|
||||
libzephyr_paths = [os.path.join(builddir, i) for i in libzephyr_paths]
|
||||
libzephyr_paths = [i for i in libzephyr_paths if os.path.exists(i)]
|
||||
return libzephyr_paths[0]
|
||||
|
||||
class ZephyrTestSuite(TestSuite):
|
||||
"""Tests for libzephyr"""
|
||||
def setup(self):
|
||||
self._libzephyr = libZephyr(find_libzephyr(self.builddir))
|
||||
|
||||
def cleanup(self):
|
||||
# no cleanup needed yet
|
||||
pass
|
||||
|
||||
def test_zinit(self):
|
||||
"""test that ZInitialize did something"""
|
||||
print "fd", self._libzephyr.ZGetFD()
|
||||
realm = self._libzephyr.ZGetRealm()
|
||||
print "realm", realm
|
||||
if not realm:
|
||||
raise TestFailure("empty realm %s" % realm)
|
||||
if self._libzephyr.Zauthtype and realm == 'local-realm':
|
||||
raise TestFailure("useless realm %s" % realm)
|
||||
if self._libzephyr.Zauthtype == 0 and realm != 'local-realm':
|
||||
raise TestFailure("wrong realm %s (should be local-realm)" % realm)
|
||||
print self._libzephyr.ZGetSender()
|
||||
|
||||
def test_notices(self):
|
||||
"""test notice construct/destruct"""
|
||||
notice = ZNotice_t()
|
||||
print "sizeof ZNotice_t", sizeof(notice)
|
||||
zbuf = c_char_p(0)
|
||||
zbuflen = c_int(0)
|
||||
st = self._libzephyr.ZFormatNotice(notice, zbuf, zbuflen, ZNOAUTH)
|
||||
print "ZFormatNotice:", "retval", st
|
||||
print "\tzbuflen", zbuflen
|
||||
print "\tzbuf", repr(zbuf.value)
|
||||
new_notice = ZNotice_t()
|
||||
st = self._libzephyr.ZParseNotice(zbuf, zbuflen, new_notice)
|
||||
print "ZParseNotice:", "retval", st
|
||||
print "\tz_version", new_notice.z_version
|
||||
ctypes_pprint(new_notice)
|
||||
|
||||
def test_z_compare_uid(self):
|
||||
"""test ZCompareUID"""
|
||||
|
||||
uid1 = ZUnique_Id_t()
|
||||
uid2 = ZUnique_Id_t()
|
||||
assert self._libzephyr.ZCompareUID(uid1, uid2), "null uids don't match"
|
||||
|
||||
# there's no ZUnique_Id_t constructor - Z_FormatHeader and Z_NewFormatHeader initialize notice->z_uid directly
|
||||
notice1 = ZNotice_t()
|
||||
zbuf = c_char_p(0)
|
||||
zbuflen = c_int(0)
|
||||
st = self._libzephyr.ZFormatNotice(notice1, zbuf, zbuflen, ZNOAUTH)
|
||||
assert st == 0, "ZFormatNotice notice1 failed"
|
||||
|
||||
notice2 = ZNotice_t()
|
||||
zbuf = c_char_p(0)
|
||||
zbuflen = c_int(0)
|
||||
st = self._libzephyr.ZFormatNotice(notice2, zbuf, zbuflen, ZNOAUTH)
|
||||
assert st == 0, "ZFormatNotice notice2 failed"
|
||||
|
||||
assert not self._libzephyr.ZCompareUID(notice1.z_uid, notice2.z_uid), "distinct notices don't compare as distinct"
|
||||
# ctypes_pprint(notice1.z_uid)
|
||||
|
||||
def test_zauthtype(self):
|
||||
"""Make sure Zauthtype is an acceptable value"""
|
||||
assert self._libzephyr.Zauthtype in (0, 4, 5)
|
||||
|
||||
def test_z_expand_realm(self):
|
||||
"""test ZExpandRealm"""
|
||||
if self._libzephyr.Zauthtype:
|
||||
assert self._libzephyr.ZExpandRealm("") == ""
|
||||
assert self._libzephyr.ZExpandRealm("localhost") == ""
|
||||
assert self._libzephyr.ZExpandRealm("bitsy.mit.edu") == "ATHENA.MIT.EDU"
|
||||
else:
|
||||
assert self._libzephyr.ZExpandRealm("") == ""
|
||||
assert self._libzephyr.ZExpandRealm("localhost") == socket.getfqdn("localhost").upper()
|
||||
assert self._libzephyr.ZExpandRealm("bitsy.mit.edu") == "BITSY.MIT.EDU"
|
||||
|
||||
def find_buildpath():
|
||||
parser = optparse.OptionParser(usage=__doc__,
|
||||
version = "%%prog %s" % __version__)
|
||||
parser.add_option("--builddir", default="..",
|
||||
help="where to find the top of the build tree")
|
||||
parser.add_option("--verbose", "-v", action="store_true",
|
||||
help="pass through for doctest.testfile")
|
||||
opts, args = parser.parse_args()
|
||||
assert not args, "no args yet"
|
||||
|
||||
return os.path.join(opts.builddir, "lib")
|
||||
|
||||
def getsockname(fd):
|
||||
"""wrapped C lib getsocketname (works on raw fd)"""
|
||||
libc = ctypes.cdll.LoadLibrary(ctypes.util.find_library("c"))
|
||||
|
||||
call_getsockname = libc.getsockname
|
||||
call_getsockname.argtypes = [
|
||||
c_int, # int s
|
||||
POINTER(sockaddr), # struct sockaddr *name
|
||||
POINTER(c_int), # socklen_t *namelen
|
||||
]
|
||||
name = sockaddr(0)
|
||||
namelen = c_int(sizeof(name))
|
||||
ret = call_getsockname(fd, name, namelen)
|
||||
if ret == 0:
|
||||
return name
|
||||
# we can't get at errno until python 2.6...
|
||||
print ret
|
||||
raise EnvironmentError("getsockname failed")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
tester = ZephyrTestSuite(builddir=find_buildpath())
|
||||
tester.setup()
|
||||
failures = tester.run()
|
||||
tester.cleanup()
|
||||
for failure, exc in failures:
|
||||
print "FAIL:", failure, str(exc)
|
362
lib/zephyr_tests.txt
Normal file
362
lib/zephyr_tests.txt
Normal file
@ -0,0 +1,362 @@
|
||||
Zephyr Library Tests
|
||||
|
||||
This file is a collection of doctests for the zephyr library.
|
||||
Minimum coverage goal is "every non-static function, and every data
|
||||
structure that shows up in those function prototypes."
|
||||
|
||||
This file is also a test of the practicality of rich doctests as API
|
||||
documentation. It will start out as a bunch of snippets, and later be
|
||||
edited to use actual chapters and appendices - narrative structure
|
||||
beyond "here's a test! here's another test!" At that point we'll also
|
||||
pick a formatting language (probably ReStructured Text but for now, we
|
||||
need no more than whitespace separated paragraphs to be
|
||||
comprehensible.)
|
||||
|
||||
Generic library setup that should be moved into zephyr_tests.py:
|
||||
|
||||
>>> import os, socket
|
||||
>>> import zephyr_tests
|
||||
>>> buildpath = zephyr_tests.find_buildpath()
|
||||
>>> libzephyr_path = zephyr_tests.find_libzephyr()
|
||||
>>> _z = zephyr_tests.libZephyr(libzephyr_path)
|
||||
|
||||
ZInit() got run by libZephyr, internally. Make sure other things
|
||||
actually got set up:
|
||||
|
||||
>>> assert _z.ZGetFD() == -1
|
||||
>>> Zauthtype = _z.Zauthtype
|
||||
>>> assert Zauthtype in (0, 4, 5)
|
||||
>>> realm = _z.ZGetRealm()
|
||||
>>> assert realm
|
||||
>>> if Zauthtype: assert realm != 'local-realm'
|
||||
>>> if not Zauthtype: assert realm == 'local-realm'
|
||||
>>> assert _z.ZGetSender()
|
||||
>>> assert "@" in _z.ZGetSender()
|
||||
|
||||
ZNotice_t structure pseudo-round-trip (needs a lot more explicit
|
||||
settings and assertions to be a real round-trip test...)
|
||||
|
||||
>>> notice = zephyr_tests.ZNotice_t()
|
||||
>>> from ctypes import sizeof
|
||||
>>> assert sizeof(notice) > 150
|
||||
>>> from ctypes import c_char_p, c_int
|
||||
>>> zbuf = c_char_p(0)
|
||||
>>> zbuflen = c_int(0)
|
||||
>>> st = _z.ZFormatNotice(notice, zbuf, zbuflen, zephyr_tests.ZNOAUTH)
|
||||
>>> assert st == 0
|
||||
>>> assert zbuf.value.startswith("ZEPH")
|
||||
>>> new_notice = zephyr_tests.ZNotice_t()
|
||||
>>> st = _z.ZParseNotice(zbuf, zbuflen, new_notice)
|
||||
>>> assert st == 0
|
||||
>>> assert new_notice.z_version.startswith("ZEPH")
|
||||
|
||||
Should we check for ZEPH0.2 now, or leave that open?
|
||||
|
||||
>>> notice = zephyr_tests.ZNotice_t()
|
||||
>>> notice.z_kind = zephyr_tests.ZNotice_Kind_t.UNSAFE
|
||||
>>> notice.z_class = c_char_p("testclass")
|
||||
>>> notice.z_class_inst = c_char_p("testinstance")
|
||||
>>> notice.z_opcode = c_char_p("TESTOPCODE")
|
||||
>>> notice.z_sender = c_char_p("someone")
|
||||
>>> notice.z_recipient = c_char_p("someone_else")
|
||||
>>> notice.z_message = c_char_p("short message body")
|
||||
>>> notice.z_message_len = c_int(len("short message body"))
|
||||
>>> zbuf = c_char_p(0)
|
||||
>>> zbuflen = c_int(0)
|
||||
>>> st = _z.ZFormatNotice(notice, zbuf, zbuflen, zephyr_tests.ZNOAUTH)
|
||||
>>> assert st == 0
|
||||
>>> assert zbuf.value.startswith("ZEPH")
|
||||
>>> new_notice = zephyr_tests.ZNotice_t()
|
||||
>>> st = _z.ZParseNotice(zbuf, zbuflen, new_notice)
|
||||
>>> assert st == 0
|
||||
>>> assert new_notice.z_version.startswith("ZEPH")
|
||||
>>> new_notice.z_class
|
||||
'testclass'
|
||||
>>> new_notice.z_class_inst
|
||||
'testinstance'
|
||||
>>> new_notice.z_opcode
|
||||
'TESTOPCODE'
|
||||
>>> new_notice.z_message[:new_notice.z_message_len]
|
||||
'short message body'
|
||||
|
||||
Simple test of ZCompareUID:
|
||||
|
||||
>>> uid1 = zephyr_tests.ZUnique_Id_t()
|
||||
>>> uid2 = zephyr_tests.ZUnique_Id_t()
|
||||
>>> assert _z.ZCompareUID(uid1, uid2), "null uids don't match"
|
||||
|
||||
There's no ZUnique_Id_t constructor - Z_FormatHeader and
|
||||
Z_NewFormatHeader initialize notice->z_uid directly, so cheat and use
|
||||
ZNotice_t as the constructor...
|
||||
|
||||
>>> notice1 = zephyr_tests.ZNotice_t()
|
||||
>>> zbuf = c_char_p(0)
|
||||
>>> zbuflen = c_int(0)
|
||||
>>> st = _z.ZFormatNotice(notice1, zbuf, zbuflen, zephyr_tests.ZNOAUTH)
|
||||
>>> assert st == 0, "ZFormatNotice notice1 failed"
|
||||
|
||||
>>> notice2 = zephyr_tests.ZNotice_t()
|
||||
>>> zbuf = c_char_p(0)
|
||||
>>> zbuflen = c_int(0)
|
||||
>>> st = _z.ZFormatNotice(notice2, zbuf, zbuflen, zephyr_tests.ZNOAUTH)
|
||||
>>> assert st == 0, "ZFormatNotice notice1 failed"
|
||||
|
||||
>>> assert not _z.ZCompareUID(notice1.z_uid, notice2.z_uid), "distinct notices don't compare as distinct"
|
||||
|
||||
Trivial test of ZExpandRealm, using terribly well known hostnames:
|
||||
|
||||
>>> assert _z.ZExpandRealm("") == ""
|
||||
>>> if Zauthtype: assert _z.ZExpandRealm("localhost") == ""
|
||||
>>> if Zauthtype: assert _z.ZExpandRealm("bitsy.mit.edu") == "ATHENA.MIT.EDU"
|
||||
>>> if not Zauthtype: assert _z.ZExpandRealm("localhost") == socket.getfqdn("localhost").upper()
|
||||
>>> if not Zauthtype: assert _z.ZExpandRealm("bitsy.mit.edu") == "BITSY.MIT.EDU"
|
||||
|
||||
ZGetCharsetString is a utility function for clients that need to know the
|
||||
full name of the output character set, e.g. zwgc. Calling it
|
||||
with NULL will get it from $ZEPHYR_CHARSET or the locale.
|
||||
Trivial testing of ZGetCharsetString:
|
||||
|
||||
>>> os.environ['LANG'] = 'C'
|
||||
>>> assert _z.ZGetCharsetString(None) == 'ANSI_X3.4-1968', "charset is " + _z.ZGetCharsetString(None)
|
||||
>>> os.environ['ZEPHYR_CHARSET'] = 'ISO-8859-1'
|
||||
>>> assert _z.ZGetCharsetString(None) == 'ISO-8859-1'
|
||||
>>> assert _z.ZGetCharsetString('UTF-8') == 'UTF-8'
|
||||
|
||||
ZGetCharset is a utility function for clients that need to know the
|
||||
registry number of a character set, e.g. zwrite. It gets its defaults from
|
||||
alal the places that ZGetCharsetString does, because it calls it.
|
||||
Trivial testing of ZGetCharset:
|
||||
|
||||
>>> assert _z.ZGetCharset(None) == 4
|
||||
>>> assert _z.ZGetCharset('NONE') == 0
|
||||
>>> assert _z.ZGetCharset('UNKNOWN') == 0
|
||||
>>> assert _z.ZGetCharset('ANSI_X3.4-1968') == 4
|
||||
>>> assert _z.ZGetCharset('ISO-8859-1') == 4
|
||||
>>> assert _z.ZGetCharset('UTF-8') == 106
|
||||
>>> assert _z.ZGetCharset('GIANT RUBBER PANTS') == 0
|
||||
|
||||
ZCharsetToString converts the registry numbers of the "allowed" character
|
||||
sets into strings.
|
||||
Trivial testing of ZCharsetToString:
|
||||
|
||||
>>> assert _z.ZCharsetToString(0) == 'UNKNOWN'
|
||||
>>> assert _z.ZCharsetToString(4) == 'ISO-8859-1'
|
||||
>>> assert _z.ZCharsetToString(106) == 'UTF-8'
|
||||
>>> assert _z.ZCharsetToString(1701) == 'UNKNOWN'
|
||||
|
||||
ZTransliterate does character set conversion for display purposes, and when
|
||||
it works, it sticks a malloc'd buffer in to **bufp.
|
||||
"Trivial" testing of ZTransliterate:
|
||||
|
||||
>>> from ctypes import c_char_p, c_int, byref, string_at
|
||||
>>> from errno import EINVAL, EILSEQ
|
||||
>>> bufp = c_char_p(None)
|
||||
>>> length = c_int(0)
|
||||
>>> assert _z.ZTransliterate('test', 4, 'ANSI_X3.4-1968', 'ANSI_X3.4-1968', byref(bufp), byref(length)) == 0
|
||||
>>> assert string_at(bufp, length) == 'test'
|
||||
>>> assert _z.ZTransliterate('test', 4, 'ANSI_X3.4-1968', 'UTF-8', byref(bufp), byref(length)) == 0
|
||||
>>> assert string_at(bufp, length) == 'test'
|
||||
>>> assert _z.ZTransliterate('test', 4, 'ISO-8859-1', 'ANSI_X3.4-1968', byref(bufp), byref(length)) == 0
|
||||
>>> assert string_at(bufp, length) == 'test'
|
||||
>>> assert _z.ZTransliterate('test', 4, 'ISO-8859-1', 'ANSI_X3.4-1968', byref(bufp), byref(length)) == 0
|
||||
>>> assert string_at(bufp, length) == 'test'
|
||||
>>> assert _z.ZTransliterate('t\xebst', 4, 'ISO-8859-1', 'ANSI_X3.4-1968', byref(bufp), byref(length)) == 0
|
||||
>>> assert string_at(bufp, length) == 't?st', "transliterated string is " + string_at(bufp, length)
|
||||
>>> assert _z.ZTransliterate('t\xebst', 4, 'ISO-8859-1', 'UTF-8', byref(bufp), byref(length)) == 0
|
||||
>>> assert string_at(bufp, length) == 't\xc3\xabst'
|
||||
>>> assert _z.ZTransliterate('t\xc3\xabst', 5, 'UTF-8', 'ISO-8859-1', byref(bufp), byref(length)) == 0
|
||||
>>> assert string_at(bufp, length) == 't\xebst'
|
||||
>>> assert _z.ZTransliterate('t\xc3\xabst', 5, 'UTF-8', 'Oh, my bees', byref(bufp), byref(length)) == EINVAL
|
||||
>>> assert _z.ZTransliterate('t\xc3x\xabst', 5, 'UTF-8', 'ISO-8859-1', byref(bufp), byref(length)) == EILSEQ
|
||||
|
||||
Trivial test of ZOpenPort and ZClosePort:
|
||||
|
||||
>>> from ctypes import c_ushort
|
||||
>>> port = c_ushort(0)
|
||||
>>> st = _z.ZOpenPort(port)
|
||||
>>> assert st == 0
|
||||
>>> assert _z.ZGetFD() != -1
|
||||
>>> zsock = zephyr_tests.getsockname(_z.ZGetFD())
|
||||
>>> assert zsock
|
||||
>>> from socket import AF_INET
|
||||
>>> assert zsock.sa_family.value == AF_INET, zsock.sa_family.value
|
||||
|
||||
(Here we're actually using getsockname as an "is that file descriptor
|
||||
a socket" test; the wrapper is weak in that it can't check for
|
||||
ENOTSOCK without requiring Python 2.6, so it just throws an exception
|
||||
on any return of -1. If ctypes.cast worked on sockaddr, we could
|
||||
also cast it to sockaddr_in and look at the address and port...)
|
||||
|
||||
>>> assert port != 0
|
||||
>>> print type(_z.ZGetDestAddr())
|
||||
<class 'zephyr_ctypes.sockaddr_in'>
|
||||
>>> print _z.ZGetDestAddr().sin_family.pformat()
|
||||
['AF_INET(2)']
|
||||
>>> print _z.ZGetDestAddr().sin_addr.pformat()
|
||||
['127.0.0.1']
|
||||
>>> assert _z.ZClosePort() == 0
|
||||
>>> assert _z.ZGetFD() == -1
|
||||
|
||||
ZMakeAscii takes a target buffer and length and an input buffer and
|
||||
length, and generates the "special" Zephyr encoding.
|
||||
|
||||
TODO: use the "reference" implementation to run a bunch of
|
||||
random-value comparison tests.
|
||||
|
||||
>>> sample = "test\0message"
|
||||
>>> ref = zephyr_tests.py_make_ascii(sample)
|
||||
>>> from ctypes import create_string_buffer
|
||||
>>> outlen = len(sample) * 6
|
||||
>>> outbuf = create_string_buffer(outlen)
|
||||
>>> st = _z.ZMakeAscii(outbuf, outlen, sample, len(sample))
|
||||
>>> assert st == 0
|
||||
>>> assert outbuf.value == ref, "%r != %r" % (outbuf.value, ref)
|
||||
|
||||
A few simple string tests:
|
||||
>>> def zma(sample):
|
||||
... outlen = len(sample) * 6
|
||||
... outbuf = create_string_buffer(outlen)
|
||||
... st = _z.ZMakeAscii(outbuf, outlen, sample, len(sample))
|
||||
... assert st == 0
|
||||
... return outbuf.value
|
||||
>>> zma("")
|
||||
''
|
||||
>>> zma("j")
|
||||
'0x6A'
|
||||
>>> zma("jK")
|
||||
'0x6A4B'
|
||||
>>> zma("jK__\0")
|
||||
'0x6A4B5F5F 0x00'
|
||||
|
||||
Same thing with ZMakeZcode, a compact binary format that is still NUL-terminated...
|
||||
|
||||
>>> sample = "test\0message"
|
||||
>>> ref = zephyr_tests.py_make_zcode(sample)
|
||||
>>> from ctypes import create_string_buffer
|
||||
>>> outlen = len(sample) * 2
|
||||
>>> outbuf = create_string_buffer(outlen)
|
||||
>>> st = _z.ZMakeZcode(outbuf, outlen, sample, len(sample))
|
||||
>>> assert st == 0
|
||||
>>> assert outbuf.value == ref, "%r != %r" % (outbuf.value, ref)
|
||||
|
||||
|
||||
Queued Packet Tests
|
||||
===================
|
||||
|
||||
Eventually we'll want tests that install a realm (or several) and
|
||||
actually send and receive packets against them, so-called "system
|
||||
tests". In the meantime, a faster and more local test that
|
||||
synthesizes packets and feeds them through the queuing mechanism will
|
||||
get us some more coverage.
|
||||
|
||||
>>> from socket import SOCK_DGRAM, socket, ntohs
|
||||
>>> port = c_ushort(0)
|
||||
>>> st = _z.ZOpenPort(port)
|
||||
>>> port = ntohs(port.value)
|
||||
>>> assert port
|
||||
>>> sock = socket(AF_INET, SOCK_DGRAM)
|
||||
>>> assert sock
|
||||
>>> assert _z.ZPending() == 0
|
||||
|
||||
TODO: cook up test-specific notices, but for now we've got some lying
|
||||
around from above...
|
||||
|
||||
>>> zwhole = string_at(zbuf, size=zbuflen)
|
||||
>>> wrote = sock.sendto(zwhole, ('127.0.0.1', port))
|
||||
>>> assert wrote == zbuflen.value, "%s != %s" % (wrote, zbuflen.value)
|
||||
>>> zcount = _z.ZPending()
|
||||
>>> assert zcount == 1
|
||||
|
||||
Coverage:
|
||||
|
||||
Files complete:
|
||||
ZOpenPort.c
|
||||
ZClosePort.c
|
||||
ZExpnRlm.c
|
||||
ZCmpUID.c
|
||||
charset.c
|
||||
ZGetSender.c (needs richer test)
|
||||
|
||||
Pending:
|
||||
|
||||
ZRequestLocations (ZAsyncLocate.c)
|
||||
ZParseLocations (ZAsyncLocate.c)
|
||||
ZCompareALDPred (ZAsyncLocate.c)
|
||||
ZFreeALD (ZAsyncLocate.c)
|
||||
ZCheckAuthentication (ZCkAuth.c)
|
||||
ZCheckIfNotice (ZCkIfNot.c)
|
||||
ZCheckZcodeAuthentication (ZCkZAut.c)
|
||||
ZCompareUIDPred (ZCmpUIDP.c)
|
||||
ZCompareMultiUIDPred (ZCmpUIDP.c)
|
||||
ZFlushLocations (ZFlsLocs.c)
|
||||
ZFlushSubscriptions (ZFlsSubs.c)
|
||||
ZFormatAuthenticNotice (ZFmtAuth.c)
|
||||
ZFormatAuthenticNoticeV5 (ZFmtAuth.c)
|
||||
ZFormatNoticeList (ZFmtList.c)
|
||||
ZFormatNotice (ZFmtNotice.c)
|
||||
ZNewFormatNotice (ZFmtNotice.c)
|
||||
ZFormatRawNotice (ZFmtRaw.c)
|
||||
ZFormatRawNoticeList (ZFmtRawLst.c)
|
||||
ZFormatSmallRawNoticeList (ZFmtSmRLst.c)
|
||||
ZFormatSmallRawNotice (ZFmtSmRaw.c)
|
||||
ZNewFormatSmallRawNotice (ZFmtSmRaw.c)
|
||||
ZFreeNotice (ZFreeNot.c)
|
||||
ZGetLocations (ZGetLocs.c)
|
||||
ZGetSubscriptions (ZGetSubs.c)
|
||||
ZGetWGPort (ZGetWGPort.c)
|
||||
ZIfNotice (ZIfNotice.c)
|
||||
ZGetRealm (ZInit.c)
|
||||
ZQLength (ZInit.c)
|
||||
ZInitLocationInfo (ZLocations.c)
|
||||
ZSetLocation (ZLocations.c)
|
||||
ZUnsetLocation (ZLocations.c)
|
||||
ZFlushMyLocations (ZLocations.c)
|
||||
ZParseExposureLevel (ZLocations.c)
|
||||
Z_SendLocation (ZLocations.c)
|
||||
ZMakeAscii32 (ZMakeAscii.c)
|
||||
ZMakeAscii16 (ZMakeAscii.c)
|
||||
ZMakeZcode32 (ZMakeZcode.c)
|
||||
ZMakeZcode (ZMakeZcode.c)
|
||||
ZResetAuthentication (ZMkAuth.c)
|
||||
ZMakeAuthentication (ZMkAuth.c)
|
||||
ZMakeZcodeAuthentication (ZMkAuth.c)
|
||||
ZMakeZcodeRealmAuthentication (ZMkAuth.c)
|
||||
ZGetCreds (ZMkAuth.c)
|
||||
ZGetCredsRealm (ZMkAuth.c)
|
||||
ZLocateUser (ZNewLocU.c)
|
||||
ZParseNotice (ZParseNot.c)
|
||||
ZPeekIfNotice (ZPeekIfNot.c)
|
||||
ZPeekNotice (ZPeekNot.c)
|
||||
ZPeekPacket (ZPeekPkt.c)
|
||||
ZPending (ZPending.c)
|
||||
ZReadAscii (ZReadAscii.c)
|
||||
ZReadAscii32 (ZReadAscii.c)
|
||||
ZReadAscii16 (ZReadAscii.c)
|
||||
ZReadZcode (ZReadZcode.c)
|
||||
ZReceiveNotice (ZRecvNot.c)
|
||||
ZReceivePacket (ZRecvPkt.c)
|
||||
ZRetrieveSubscriptions (ZRetSubs.c)
|
||||
ZRetrieveDefaultSubscriptions (ZRetSubs.c)
|
||||
ZSendList (ZSendList.c)
|
||||
ZSrvSendList (ZSendList.c)
|
||||
ZSendNotice (ZSendNot.c)
|
||||
ZSrvSendNotice (ZSendNot.c)
|
||||
ZSendPacket (ZSendPkt.c)
|
||||
ZSendRawList (ZSendRLst.c)
|
||||
ZSrvSendRawList (ZSendRLst.c)
|
||||
ZSendRawNotice (ZSendRaw.c)
|
||||
ZSetDestAddr (ZSetDest.c)
|
||||
ZSetFD (ZSetFD.c)
|
||||
ZSetServerState (ZSetSrv.c)
|
||||
ZPunt (ZSubs.c)
|
||||
ZSubscribeTo (ZSubs.c)
|
||||
ZSubscribeToSansDefaults (ZSubs.c)
|
||||
ZUnsubscribeTo (ZSubs.c)
|
||||
ZCancelSubscriptions (ZSubs.c)
|
||||
ZGetVariable (ZVariables.c)
|
||||
ZSetVariable (ZVariables.c)
|
||||
ZUnsetVariable (ZVariables.c)
|
||||
Z_WaitForNotice (ZWait4Not.c)
|
||||
ZhmStat (ZhmStat.c)
|
||||
|
||||
(...continue with Zinternal.c...)
|
Reference in New Issue
Block a user