ncpl_bind.c revision 84213
152153Sbp/*
252153Sbp * Copyright (c) 1999, Boris Popov
352153Sbp * All rights reserved.
452153Sbp *
552153Sbp * Redistribution and use in source and binary forms, with or without
652153Sbp * modification, are permitted provided that the following conditions
752153Sbp * are met:
852153Sbp * 1. Redistributions of source code must retain the above copyright
952153Sbp *    notice, this list of conditions and the following disclaimer.
1052153Sbp * 2. Redistributions in binary form must reproduce the above copyright
1152153Sbp *    notice, this list of conditions and the following disclaimer in the
1252153Sbp *    documentation and/or other materials provided with the distribution.
1352153Sbp * 3. All advertising materials mentioning features or use of this software
1452153Sbp *    must display the following acknowledgement:
1552153Sbp *    This product includes software developed by Boris Popov.
1652153Sbp * 4. Neither the name of the author nor the names of any co-contributors
1752153Sbp *    may be used to endorse or promote products derived from this software
1852153Sbp *    without specific prior written permission.
1952153Sbp *
2052153Sbp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2152153Sbp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2252153Sbp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2352153Sbp * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2452153Sbp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2552153Sbp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2652153Sbp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2752153Sbp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2852153Sbp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2952153Sbp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3052153Sbp * SUCH DAMAGE.
3152153Sbp */
3284213Sdillon
3384213Sdillon#include <sys/cdefs.h>
3484213Sdillon__FBSDID("$FreeBSD: head/lib/libncp/ncpl_bind.c 84213 2001-09-30 22:01:19Z dillon $");
3584213Sdillon
3652153Sbp#include <sys/types.h>
3752153Sbp#include <errno.h>
3852153Sbp#include <string.h>
3952153Sbp#include <netncp/ncp_lib.h>
4052153Sbp
4152153Sbpstatic void nw_passencrypt(char *old, char *new, char *out);
4252153Sbp
4352153Sbpint
4452704Sbpncp_get_bindery_object_id(NWCONN_HANDLE connid, u_int16_t object_type,
4552704Sbp	const char *object_name, struct ncp_bindery_object *target)
4652704Sbp{
4752153Sbp	int error;
4852153Sbp	DECLARE_RQ;
4952153Sbp
5052153Sbp	ncp_init_request_s(conn, 53);
5152153Sbp	ncp_add_word_hl(conn, object_type);
5252153Sbp	ncp_add_pstring(conn, object_name);
5352153Sbp
5452153Sbp	if ((error = ncp_request(connid, 23, conn)) != 0) {
5552153Sbp		return error;
5652153Sbp	}
5752153Sbp	if (conn->rpsize < 54) {
5852153Sbp		return EACCES;
5952153Sbp	}
6052153Sbp	target->object_id = ncp_reply_dword_hl(conn, 0);
6152153Sbp	target->object_type = ncp_reply_word_hl(conn, 4);
6252153Sbp	memcpy(target->object_name, ncp_reply_data(conn, 6), 48);
6352153Sbp	return 0;
6452153Sbp}
6552153Sbp
6652153Sbpint
6752704Sbpncp_read_property_value(NWCONN_HANDLE connid, int object_type,
6852704Sbp	const char *object_name, int segment, const char *prop_name,
6952704Sbp	struct nw_property *target)
7052153Sbp{
7152153Sbp	int error;
7252153Sbp	struct ncp_buf conn;
7352153Sbp	ncp_init_request_s(&conn, 61);
7452153Sbp	ncp_add_word_hl(&conn, object_type);
7552153Sbp	ncp_add_pstring(&conn, object_name);
7652153Sbp	ncp_add_byte(&conn, segment);
7752153Sbp	ncp_add_pstring(&conn, prop_name);
7852153Sbp
7952153Sbp	if ((error = ncp_request(connid,23,&conn)) != 0) {
8052153Sbp		return error;
8152153Sbp	}
8252153Sbp	memcpy(&(target->value), ncp_reply_data(&conn, 0), 128);
8352153Sbp	target->more_flag = ncp_reply_byte(&conn, 128);
8452153Sbp	target->property_flag = ncp_reply_byte(&conn, 129);
8552153Sbp	return 0;
8652153Sbp}
8752153Sbp
8852153Sbpint
8952704Sbpncp_scan_bindery_object(NWCONN_HANDLE connid, u_int32_t last_id,
9052704Sbp	u_int16_t object_type, char *search_string,
9152704Sbp	struct ncp_bindery_object *target)
9252153Sbp{
9352153Sbp	int error;
9452153Sbp	DECLARE_RQ;
9552153Sbp
9652153Sbp	ncp_init_request_s(conn, 55);
9752153Sbp	ncp_add_dword_hl(conn, last_id);
9852153Sbp	ncp_add_word_hl(conn, object_type);
9952153Sbp	ncp_add_pstring(conn, search_string);
10052153Sbp	error = ncp_request(connid, 23, conn);
10152153Sbp	if (error) return error;
10252153Sbp	target->object_id = ncp_reply_dword_hl(conn, 0);
10352153Sbp	target->object_type = ncp_reply_word_hl(conn, 4);
10452153Sbp	memcpy(target->object_name, ncp_reply_data(conn, 6),NCP_BINDERY_NAME_LEN);
10552153Sbp	target->object_flags = ncp_reply_byte(conn, 54);
10652153Sbp	target->object_security = ncp_reply_byte(conn, 55);
10752153Sbp	target->object_has_prop = ncp_reply_byte(conn, 56);
10852153Sbp	return 0;
10952153Sbp}
11052153Sbp
11152153Sbpint
11252704Sbpncp_get_bindery_object_name(NWCONN_HANDLE connid, u_int32_t object_id,
11352704Sbp	struct ncp_bindery_object *target)
11452704Sbp{
11552153Sbp	int error;
11652153Sbp	DECLARE_RQ;
11752153Sbp
11852153Sbp	ncp_init_request_s(conn, 54);
11952153Sbp	ncp_add_dword_hl(conn, object_id);
12052153Sbp	if ((error = ncp_request(connid, 23, conn)) != 0)
12152153Sbp		return error;
12252153Sbp	target->object_id = ncp_reply_dword_hl(conn, 0);
12352153Sbp	target->object_type = ncp_reply_word_hl(conn, 4);
12452153Sbp	memcpy(target->object_name, ncp_reply_data(conn, 6), 48);
12552153Sbp	return 0;
12652153Sbp}
12752153Sbp
12852153Sbpint
12952153Sbpncp_change_obj_passwd(NWCONN_HANDLE connid,
13052153Sbp	const struct ncp_bindery_object *object,
13152153Sbp	const u_char *key,
13252153Sbp	const u_char *oldpasswd,
13352153Sbp	const u_char *newpasswd)
13452153Sbp{
13552153Sbp	long id = htonl(object->object_id);
13652153Sbp	u_char cryptkey[8];
13752153Sbp	u_char newpwd[16];	/* new passwd as stored by server */
13852153Sbp	u_char oldpwd[16];	/* old passwd as stored by server */
13952153Sbp	u_char len;
14052153Sbp	DECLARE_RQ;
14152153Sbp
14252153Sbp	memcpy(cryptkey, key, 8);
14352153Sbp	nw_keyhash((u_char *)&id, oldpasswd, strlen(oldpasswd), oldpwd);
14452153Sbp	nw_keyhash((u_char *)&id, newpasswd, strlen(newpasswd), newpwd);
14552153Sbp	nw_encrypt(cryptkey, oldpwd, cryptkey);
14652153Sbp	nw_passencrypt(oldpwd, newpwd, newpwd);
14752153Sbp	nw_passencrypt(oldpwd + 8, newpwd + 8, newpwd + 8);
14852153Sbp	if ((len = strlen(newpasswd)) > 63) {
14952153Sbp		len = 63;
15052153Sbp	}
15152153Sbp	len = ((len ^ oldpwd[0] ^ oldpwd[1]) & 0x7f) | 0x40;
15252153Sbp
15352153Sbp	ncp_init_request_s(conn, 75);
15452153Sbp	ncp_add_mem(conn, cryptkey, 8);
15552153Sbp	ncp_add_word_hl(conn, object->object_type);
15652153Sbp	ncp_add_pstring(conn, object->object_name);
15752153Sbp	ncp_add_byte(conn, len);
15852153Sbp	ncp_add_mem(conn, newpwd, 16);
15952153Sbp	return ncp_request(connid, 23, conn);
16052153Sbp}
16152153Sbp
16252153Sbp/*
16352153Sbp * target is a 8-byte buffer
16452153Sbp */
16552153Sbpint
16652153Sbpncp_get_encryption_key(NWCONN_HANDLE cH, char *target) {
16752153Sbp	int error;
16852153Sbp	DECLARE_RQ;
16952153Sbp
17052153Sbp	ncp_init_request_s(conn, 23);
17152153Sbp
17252153Sbp	error = ncp_request(cH, 23, conn);
17352153Sbp	if (error)
17452153Sbp		return error;
17552153Sbp	if (conn->rpsize < 8)
17652153Sbp		return EACCES;
17752153Sbp	memcpy(target, ncp_reply_data(conn, 0), 8);
17852153Sbp	return 0;
17952153Sbp}
18052153Sbp
18152153Sbpint
18252153Sbpncp_keyed_verify_password(NWCONN_HANDLE cH, char *key, char *passwd,
18352704Sbp	struct ncp_bindery_object *objinfo)
18452704Sbp{
18552153Sbp	u_long id = htonl(objinfo->object_id);
18652153Sbp	u_char cryptkey[8];
18752153Sbp	u_char buf[128];
18852153Sbp	DECLARE_RQ;
18952153Sbp
19052153Sbp	nw_keyhash((u_char *)&id, passwd, strlen(passwd), buf);
19152153Sbp	nw_encrypt(key, buf, cryptkey);
19252153Sbp
19352153Sbp	ncp_init_request_s(conn, 74);
19452153Sbp	ncp_add_mem(conn, cryptkey, sizeof(cryptkey));
19552153Sbp	ncp_add_word_hl(conn, objinfo->object_type);
19652153Sbp	ncp_add_pstring(conn, objinfo->object_name);
19752153Sbp
19852153Sbp	return ncp_request(cH, 23, conn);
19952153Sbp}
20052153Sbp
20152153Sbpstatic char passkeys[256 + 16] = {
20252153Sbp	0x0f, 0x08, 0x05, 0x07, 0x0c, 0x02, 0x0e, 0x09,
20352153Sbp	0x00, 0x01, 0x06, 0x0d, 0x03, 0x04, 0x0b, 0x0a,
20452153Sbp	0x02, 0x0c, 0x0e, 0x06, 0x0f, 0x00, 0x01, 0x08,
20552153Sbp	0x0d, 0x03, 0x0a, 0x04, 0x09, 0x0b, 0x05, 0x07,
20652153Sbp	0x05, 0x02, 0x09, 0x0f, 0x0c, 0x04, 0x0d, 0x00,
20752153Sbp	0x0e, 0x0a, 0x06, 0x08, 0x0b, 0x01, 0x03, 0x07,
20852153Sbp	0x0f, 0x0d, 0x02, 0x06, 0x07, 0x08, 0x05, 0x09,
20952153Sbp	0x00, 0x04, 0x0c, 0x03, 0x01, 0x0a, 0x0b, 0x0e,
21052153Sbp	0x05, 0x0e, 0x02, 0x0b, 0x0d, 0x0a, 0x07, 0x00,
21152153Sbp	0x08, 0x06, 0x04, 0x01, 0x0f, 0x0c, 0x03, 0x09,
21252153Sbp	0x08, 0x02, 0x0f, 0x0a, 0x05, 0x09, 0x06, 0x0c,
21352153Sbp	0x00, 0x0b, 0x01, 0x0d, 0x07, 0x03, 0x04, 0x0e,
21452153Sbp	0x0e, 0x08, 0x00, 0x09, 0x04, 0x0b, 0x02, 0x07,
21552153Sbp	0x0c, 0x03, 0x0a, 0x05, 0x0d, 0x01, 0x06, 0x0f,
21652153Sbp	0x01, 0x04, 0x08, 0x0a, 0x0d, 0x0b, 0x07, 0x0e,
21752153Sbp	0x05, 0x0f, 0x03, 0x09, 0x00, 0x02, 0x06, 0x0c,
21852153Sbp	0x05, 0x03, 0x0c, 0x08, 0x0b, 0x02, 0x0e, 0x0a,
21952153Sbp	0x04, 0x01, 0x0d, 0x00, 0x06, 0x07, 0x0f, 0x09,
22052153Sbp	0x06, 0x00, 0x0b, 0x0e, 0x0d, 0x04, 0x0c, 0x0f,
22152153Sbp	0x07, 0x02, 0x08, 0x0a, 0x01, 0x05, 0x03, 0x09,
22252153Sbp	0x0b, 0x05, 0x0a, 0x0e, 0x0f, 0x01, 0x0c, 0x00,
22352153Sbp	0x06, 0x04, 0x02, 0x09, 0x03, 0x0d, 0x07, 0x08,
22452153Sbp	0x07, 0x02, 0x0a, 0x00, 0x0e, 0x08, 0x0f, 0x04,
22552153Sbp	0x0c, 0x0b, 0x09, 0x01, 0x05, 0x0d, 0x03, 0x06,
22652153Sbp	0x07, 0x04, 0x0f, 0x09, 0x05, 0x01, 0x0c, 0x0b,
22752153Sbp	0x00, 0x03, 0x08, 0x0e, 0x02, 0x0a, 0x06, 0x0d,
22852153Sbp	0x09, 0x04, 0x08, 0x00, 0x0a, 0x03, 0x01, 0x0c,
22952153Sbp	0x05, 0x0f, 0x07, 0x02, 0x0b, 0x0e, 0x06, 0x0d,
23052153Sbp	0x09, 0x05, 0x04, 0x07, 0x0e, 0x08, 0x03, 0x01,
23152153Sbp	0x0d, 0x0b, 0x0c, 0x02, 0x00, 0x0f, 0x06, 0x0a,
23252153Sbp	0x09, 0x0a, 0x0b, 0x0d, 0x05, 0x03, 0x0f, 0x00,
23352153Sbp	0x01, 0x0c, 0x08, 0x07, 0x06, 0x04, 0x0e, 0x02,
23452153Sbp	0x03, 0x0e, 0x0f, 0x02, 0x0d, 0x0c, 0x04, 0x05,
23552153Sbp	0x09, 0x06, 0x00, 0x01, 0x0b, 0x07, 0x0a, 0x08
23652153Sbp};
23752153Sbp
23852153Sbpstatic void
23952153Sbpnw_passencrypt(char *old, char *new, char *out)
24052153Sbp{
24152153Sbp	char *p, v;
24252153Sbp	char copy[8];
24352153Sbp	int i, di, ax;
24452153Sbp
24552153Sbp#define HIGH(x)	(((x) >> 4) & 0xf)
24652153Sbp#define LOW(x)	((x) & 0xf)
24752153Sbp	memcpy(copy, new, 8);
24852153Sbp
24952153Sbp	for (i = 0; i < 16; i++) {
25052153Sbp		for (di = 0, ax = 0, p = old; di < 8; di++, ax += 0x20, p++) {
25152153Sbp			v = copy[di] ^ *p;
25252153Sbp			copy[di] = (passkeys[HIGH(v) + ax + 0x10] << 4) |
25352153Sbp				   passkeys[LOW(v) + ax];
25452153Sbp		}
25552153Sbp		v = old[7];
25652153Sbp		for (p = old + 7; p > old; p--) {
25752153Sbp			*p = HIGH(p[-1]) | ((*p) << 4);
25852153Sbp		}
25952153Sbp		*old = HIGH(v) | (*old) << 4;
26052153Sbp		bzero(out, 8);
26152153Sbp
26252153Sbp		for (di = 0; di < 16; di++) {
26352153Sbp			v = passkeys[di + 0x100];
26452153Sbp			v = (v & 1) ? HIGH(copy[v / 2]) : LOW(copy[v / 2]);
26552153Sbp			out[di / 2] |= ((di & 1) ? v << 4 : v);
26652153Sbp		}
26752153Sbp		memcpy(copy, out, 8);
26852153Sbp	}
26952153Sbp}
270