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