⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 security-util.c

📁 开源备份软件源码 AMANDA, the Advanced Maryland Automatic Network Disk Archiver, is a backup system that a
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (*size > 128*NETWORK_BLOCK_BYTES || *size < 0) {	if (isprint((int)(*size        ) & 0xFF) &&	    isprint((int)(*size   >> 8 ) & 0xFF) &&	    isprint((int)(*size   >> 16) & 0xFF) &&	    isprint((int)(*size   >> 24) & 0xFF) &&	    isprint((*handle      ) & 0xFF) &&	    isprint((*handle >> 8 ) & 0xFF) &&	    isprint((*handle >> 16) & 0xFF) &&	    isprint((*handle >> 24) & 0xFF)) {	    char s[101];	    int i;	    s[0] = ((int)(*size)  >> 24) & 0xFF;	    s[1] = ((int)(*size)  >> 16) & 0xFF;	    s[2] = ((int)(*size)  >>  8) & 0xFF;	    s[3] = ((int)(*size)       ) & 0xFF;	    s[4] = (*handle >> 24) & 0xFF;	    s[5] = (*handle >> 16) & 0xFF;	    s[6] = (*handle >> 8 ) & 0xFF;	    s[7] = (*handle      ) & 0xFF;	    i = 8; s[i] = ' ';	    while(i<100 && isprint((int)s[i]) && s[i] != '\n') {		switch(net_read(fd, &s[i], 1, 0)) {		case -1: s[i] = '\0'; break;		case  0: s[i] = '\0'; break;		default:			 dbprintf(_("read: %c\n"), s[i]); i++; s[i]=' ';			 break;		}	    }	    s[i] = '\0';	    *errmsg = newvstrallocf(*errmsg, _("tcpm_recv_token: invalid size: %s"), s);	    dbprintf(_("tcpm_recv_token: invalid size %s\n"), s);	} else {	    *errmsg = newvstrallocf(*errmsg, _("tcpm_recv_token: invalid size"));	    dbprintf(_("tcpm_recv_token: invalid size %zd\n"), *size);	}	*size = -1;	return -1;    }    amfree(*buf);    *buf = alloc((size_t)*size);    if(*size == 0) {	auth_debug(1, _("tcpm_recv_token: read EOF from %d\n"), *handle);	*errmsg = newvstrallocf(*errmsg, _("EOF"));	return 0;    }    switch (net_read(fd, *buf, (size_t)*size, timeout)) {    case -1:	if (errmsg)	    *errmsg = newvstrallocf(*errmsg, _("recv error: %s"), strerror(errno));	auth_debug(1, _("tcpm_recv_token: B return(-1)\n"));	return (-1);    case 0:	*size = 0;	*errmsg = newvstrallocf(*errmsg, _("SOCKET_EOF"));	auth_debug(1, _("tcpm_recv_token: B return(0)\n"));	return (0);    default:	break;    }    auth_debug(1, _("tcpm_recv_token: read %zd bytes from %d\n"), *size, *handle);    if (*size > 0 && rc->driver->data_decrypt != NULL) {	void *decbuf;	ssize_t decsize;	rc->driver->data_decrypt(rc, *buf, *size, &decbuf, &decsize);	if (*buf != (char *)decbuf) {	    amfree(*buf);	    *buf = (char *)decbuf;	}	*size = decsize;    }    return((*size));}voidtcpm_close_connection(    void *h,    char *hostname){    struct sec_handle *rh = h;    (void)hostname;    if (rh && rh->rc && rh->rc->toclose == 0) {	rh->rc->toclose = 1;	sec_tcp_conn_put(rh->rc);    }}/* * Accept an incoming connection on a stream_server socket * Nothing needed for tcpma. */inttcpma_stream_accept(    void *	s){    (void)s;	/* Quiet unused parameter warning */    return (0);}/* * Return a connected stream.  For sec, this means setup a stream * with the supplied handle. */void *tcpma_stream_client(    void *	h,    int		id){    struct sec_handle *rh = h;    struct sec_stream *rs;    assert(rh != NULL);    if (id <= 0) {	security_seterror(&rh->sech,	    _("%d: invalid security stream id"), id);	return (NULL);    }    rs = alloc(SIZEOF(*rs));    security_streaminit(&rs->secstr, rh->sech.driver);    rs->handle = id;    rs->ev_read = NULL;    rs->closed_by_me = 0;    rs->closed_by_network = 0;    if (rh->rc) {	rs->rc = rh->rc;	rh->rc->refcnt++;    }    else {	rs->rc = sec_tcp_conn_get(rh->hostname, 0);	rs->rc->driver = rh->sech.driver;	rh->rc = rs->rc;    }    auth_debug(1, _("sec: stream_client: connected to stream %d\n"), id);    return (rs);}/* * Create the server end of a stream.  For sec, this means setup a stream * object and allocate a new handle for it. */void *tcpma_stream_server(    void *	h){    struct sec_handle *rh = h;    struct sec_stream *rs;    assert(rh != NULL);    rs = alloc(SIZEOF(*rs));    security_streaminit(&rs->secstr, rh->sech.driver);    rs->closed_by_me = 0;    rs->closed_by_network = 0;    if (rh->rc) {	rs->rc = rh->rc;	rs->rc->refcnt++;    }    else {	rs->rc = sec_tcp_conn_get(rh->hostname, 0);	rs->rc->driver = rh->sech.driver;	rh->rc = rs->rc;    }    /*     * Stream should already be setup!     */    if (rs->rc->read < 0) {	sec_tcp_conn_put(rs->rc);	amfree(rs);	security_seterror(&rh->sech, _("lost connection to %s"), rh->hostname);	return (NULL);    }    assert(strcmp(rh->hostname, rs->rc->hostname) == 0);    /*     * so as not to conflict with the amanda server's handle numbers,     * we start at 500000 and work down     */    rs->handle = 500000 - newhandle++;    rs->ev_read = NULL;    auth_debug(1, _("sec: stream_server: created stream %d\n"), rs->handle);    return (rs);}/* * Close and unallocate resources for a stream. */voidtcpma_stream_close(    void *	s){    struct sec_stream *rs = s;    char buf = 0;    assert(rs != NULL);    auth_debug(1, _("sec: tcpma_stream_close: closing stream %d\n"), rs->handle);    if(rs->closed_by_network == 0 && rs->rc->write != -1)	tcpm_stream_write(rs, &buf, 0);    security_stream_read_cancel(&rs->secstr);    if(rs->closed_by_network == 0)	sec_tcp_conn_put(rs->rc);    amfree(rs);}/* * Create the server end of a stream.  For bsdudp, this means setup a tcp * socket for receiving a connection. */void *tcp1_stream_server(    void *	h){    struct sec_stream *rs = NULL;    struct sec_handle *rh = h;    assert(rh != NULL);    rs = alloc(SIZEOF(*rs));    security_streaminit(&rs->secstr, rh->sech.driver);    rs->closed_by_me = 0;    rs->closed_by_network = 0;    if (rh->rc) {	rs->rc = rh->rc;	rs->handle = 500000 - newhandle++;	rs->rc->refcnt++;	rs->socket = 0;		/* the socket is already opened */    }    else {	rh->rc = sec_tcp_conn_get(rh->hostname, 1);	rh->rc->driver = rh->sech.driver;	rs->rc = rh->rc;	rs->socket = stream_server(rh->udp->peer.ss_family, &rs->port,				   STREAM_BUFSIZE, STREAM_BUFSIZE, 0);	if (rs->socket < 0) {	    security_seterror(&rh->sech,			    _("can't create server stream: %s"), strerror(errno));	    amfree(rs);	    return (NULL);	}	rh->rc->read = rs->socket;	rh->rc->write = rs->socket;	rs->handle = (int)rs->port;    }    rs->fd = -1;    rs->ev_read = NULL;    return (rs);}/* * Accepts a new connection on unconnected streams.  Assumes it is ok to * block on accept() */inttcp1_stream_accept(    void *	s){    struct sec_stream *bs = s;    assert(bs != NULL);    assert(bs->socket != -1);    assert(bs->fd < 0);    if (bs->socket > 0) {	bs->fd = stream_accept(bs->socket, 30, STREAM_BUFSIZE, STREAM_BUFSIZE);	if (bs->fd < 0) {	    security_stream_seterror(&bs->secstr,				     _("can't accept new stream connection: %s"),				     strerror(errno));	    return (-1);	}	bs->rc->read = bs->fd;	bs->rc->write = bs->fd;    }    return (0);}/* * Return a connected stream */void *tcp1_stream_client(    void *	h,    int		id){    struct sec_stream *rs = NULL;    struct sec_handle *rh = h;    assert(rh != NULL);    rs = alloc(SIZEOF(*rs));    security_streaminit(&rs->secstr, rh->sech.driver);    rs->handle = id;    rs->ev_read = NULL;    rs->closed_by_me = 0;    rs->closed_by_network = 0;    if (rh->rc) {	rs->rc = rh->rc;	rh->rc->refcnt++;    }    else {	rh->rc = sec_tcp_conn_get(rh->hostname, 1);	rh->rc->driver = rh->sech.driver;	rs->rc = rh->rc;	rh->rc->read = stream_client(rh->hostname, (in_port_t)id,			STREAM_BUFSIZE, STREAM_BUFSIZE, &rs->port, 0);	if (rh->rc->read < 0) {	    security_seterror(&rh->sech,			      _("can't connect stream to %s port %d: %s"),			       rh->hostname, id, strerror(errno));	    amfree(rs);	    return (NULL);        }	rh->rc->write = rh->rc->read;    }    rs->socket = -1;	/* we're a client */    rh->rs = rs;    return (rs);}inttcp_stream_write(    void *	s,    const void *buf,    size_t	size){    struct sec_stream *rs = s;    assert(rs != NULL);    if (fullwrite(rs->fd, buf, size) < 0) {        security_stream_seterror(&rs->secstr,            _("write error on stream %d: %s"), rs->port, strerror(errno));        return (-1);    }    return (0);}char *bsd_prefix_packet(    void *	h,    pkt_t *	pkt){    struct sec_handle *rh = h;    struct passwd *pwd;    char *buf;    if (pkt->type != P_REQ)	return "";    if ((pwd = getpwuid(getuid())) == NULL) {	security_seterror(&rh->sech,			  _("can't get login name for my uid %ld"),			  (long)getuid());	return(NULL);    }    buf = alloc(16+strlen(pwd->pw_name));    strncpy(buf, "SECURITY USER ", (16 + strlen(pwd->pw_name)));    strncpy(&buf[14], pwd->pw_name, (16 + strlen(pwd->pw_name) - 14));    buf[14 + strlen(pwd->pw_name)] = '\n';    buf[15 + strlen(pwd->pw_name)] = '\0';    return (buf);}/* * Check the security of a received packet.  Returns negative on security * violation, or returns 0 if ok.  Removes the security info from the pkt_t. */intbsd_recv_security_ok(    struct sec_handle *	rh,    pkt_t *		pkt){    char *tok, *security, *body, *result;    char *service = NULL, *serviceX, *serviceY;    char *security_line;    char *s, ch;    size_t len;    in_port_t port;    /*     * Now, find the SECURITY line in the body, and parse it out     * into an argv.     */    if (strncmp_const(pkt->body, "SECURITY ") == 0) {	security = pkt->body;	len = 0;	while(*security != '\n' && len < pkt->size) {	    security++;	    len++;	}	if(*security == '\n') {	    body = security+1;	    *security = '\0';	    security_line = stralloc(pkt->body);	    security = pkt->body + strlen("SECURITY ");	} else {	    body = pkt->body;	    security_line = NULL;	    security = NULL;	}    } else {	body = pkt->body;	security_line = NULL;	security = NULL;    }    /*     * Now, find the SERVICE line in the body, and parse it out     * into an argv.     */    s = body;    if (strncmp_const_skip(s, "SERVICE ", s, ch) == 0) {	serviceX = stralloc(s);	serviceY = strtok(serviceX, "\n");	if (serviceY)	    service  = stralloc(serviceY);	amfree(serviceX);    }    /*     * We need to do different things depending on which type of packet     * this is.     */    switch (pkt->type) {    case P_REQ:	/*	 * Request packets must come from a reserved port	 */    port = SS_GET_PORT(&rh->peer);	if (port >= IPPORT_RESERVED) {	    security_seterror(&rh->sech,		_("host %s: port %u not secure"), rh->hostname,		(unsigned int)port);	    amfree(service);	    amfree(security_line);	    return (-1);	}	if (!service) {	    security_seterror(&rh->sech,			      _("packet as no SERVICE line"));	    amfree(security_line);	    return (-1);	}	/*	 * Request packets contain a remote username.  We need to check	 * that we allow it in.	 *	 * They will look like:	 *	SECURITY USER [username]	 */	/* there must be some security info */	if (security == NULL) {	    security_seterror(&rh->sech,		_("no bsd SECURITY for P_REQ"));	    amfree(service);	    return (-1);	}	/* second word must be USER */	if ((tok = strtok(security, " ")) == NULL) {	    security_seterror(&rh->sech,		_("SECURITY line: %s"), security_line);	    amfree(service);	    amfree(security_line);	    return (-1);	/* default errmsg */	}	if (strcmp(tok, "USER") != 0) {	    security_seterror(&rh->sech,		_("REQ SECURITY line parse error, expecting USER, got %s"), tok);	    amfree(service);	    amfree(security_line);	    return (-1);	}	/* the third word is the username */	if ((tok = strtok(NULL, "")) == NULL) {	    security_seterror(&rh->sech,		_("SECURITY line: %s"), security_line);	    amfree(security_line);	    return (-1);	/* default errmsg */	}	if ((result = check_user(rh, tok, service)) != NULL) {	    security_seterror(&rh->sech, "%s", result);	    amfree(service);	    amfree(result);	    amfree(security_line);	    return (-1);	}	/* we're good to go */	break;    default:	break;    }    amfree(service);    amfree(security_line);    /*     * If there is security info at the front of the packet, we need to     * shift the rest of the data up and nuke it.     */    if (body != pkt->body)	memmove(pkt->body, body, strlen(body) + 1);    return (0);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -