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. 13165920Simp * 3. Neither the name of the author nor the names of any co-contributors 1452153Sbp * may be used to endorse or promote products derived from this software 1552153Sbp * without specific prior written permission. 1652153Sbp * 1752153Sbp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1852153Sbp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1952153Sbp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2052153Sbp * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2152153Sbp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2252153Sbp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2352153Sbp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2452153Sbp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2552153Sbp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2652153Sbp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2752153Sbp * SUCH DAMAGE. 2852153Sbp */ 2984213Sdillon 3084213Sdillon#include <sys/cdefs.h> 3184213Sdillon__FBSDID("$FreeBSD$"); 3284213Sdillon 3352153Sbp#include <sys/types.h> 3490868Smike#include <arpa/inet.h> 3552153Sbp#include <errno.h> 3652153Sbp#include <string.h> 3752153Sbp#include <netncp/ncp_lib.h> 3852153Sbp 3952153Sbpstatic void nw_passencrypt(char *old, char *new, char *out); 4052153Sbp 4152153Sbpint 4252704Sbpncp_get_bindery_object_id(NWCONN_HANDLE connid, u_int16_t object_type, 4352704Sbp const char *object_name, struct ncp_bindery_object *target) 4452704Sbp{ 4552153Sbp int error; 4652153Sbp DECLARE_RQ; 4752153Sbp 4852153Sbp ncp_init_request_s(conn, 53); 4952153Sbp ncp_add_word_hl(conn, object_type); 5052153Sbp ncp_add_pstring(conn, object_name); 5152153Sbp 5252153Sbp if ((error = ncp_request(connid, 23, conn)) != 0) { 5352153Sbp return error; 5452153Sbp } 5552153Sbp if (conn->rpsize < 54) { 5652153Sbp return EACCES; 5752153Sbp } 5852153Sbp target->object_id = ncp_reply_dword_hl(conn, 0); 5952153Sbp target->object_type = ncp_reply_word_hl(conn, 4); 6052153Sbp memcpy(target->object_name, ncp_reply_data(conn, 6), 48); 6152153Sbp return 0; 6252153Sbp} 6352153Sbp 6452153Sbpint 6552704Sbpncp_read_property_value(NWCONN_HANDLE connid, int object_type, 6652704Sbp const char *object_name, int segment, const char *prop_name, 6752704Sbp struct nw_property *target) 6852153Sbp{ 6952153Sbp int error; 7052153Sbp struct ncp_buf conn; 7152153Sbp ncp_init_request_s(&conn, 61); 7252153Sbp ncp_add_word_hl(&conn, object_type); 7352153Sbp ncp_add_pstring(&conn, object_name); 7452153Sbp ncp_add_byte(&conn, segment); 7552153Sbp ncp_add_pstring(&conn, prop_name); 7652153Sbp 7752153Sbp if ((error = ncp_request(connid,23,&conn)) != 0) { 7852153Sbp return error; 7952153Sbp } 8052153Sbp memcpy(&(target->value), ncp_reply_data(&conn, 0), 128); 8152153Sbp target->more_flag = ncp_reply_byte(&conn, 128); 8252153Sbp target->property_flag = ncp_reply_byte(&conn, 129); 8352153Sbp return 0; 8452153Sbp} 8552153Sbp 8652153Sbpint 8752704Sbpncp_scan_bindery_object(NWCONN_HANDLE connid, u_int32_t last_id, 8852704Sbp u_int16_t object_type, char *search_string, 8952704Sbp struct ncp_bindery_object *target) 9052153Sbp{ 9152153Sbp int error; 9252153Sbp DECLARE_RQ; 9352153Sbp 9452153Sbp ncp_init_request_s(conn, 55); 9552153Sbp ncp_add_dword_hl(conn, last_id); 9652153Sbp ncp_add_word_hl(conn, object_type); 9752153Sbp ncp_add_pstring(conn, search_string); 9852153Sbp error = ncp_request(connid, 23, conn); 9952153Sbp if (error) return error; 10052153Sbp target->object_id = ncp_reply_dword_hl(conn, 0); 10152153Sbp target->object_type = ncp_reply_word_hl(conn, 4); 10252153Sbp memcpy(target->object_name, ncp_reply_data(conn, 6),NCP_BINDERY_NAME_LEN); 10352153Sbp target->object_flags = ncp_reply_byte(conn, 54); 10452153Sbp target->object_security = ncp_reply_byte(conn, 55); 10552153Sbp target->object_has_prop = ncp_reply_byte(conn, 56); 10652153Sbp return 0; 10752153Sbp} 10852153Sbp 10952153Sbpint 11052704Sbpncp_get_bindery_object_name(NWCONN_HANDLE connid, u_int32_t object_id, 11152704Sbp struct ncp_bindery_object *target) 11252704Sbp{ 11352153Sbp int error; 11452153Sbp DECLARE_RQ; 11552153Sbp 11652153Sbp ncp_init_request_s(conn, 54); 11752153Sbp ncp_add_dword_hl(conn, object_id); 11852153Sbp if ((error = ncp_request(connid, 23, conn)) != 0) 11952153Sbp return error; 12052153Sbp target->object_id = ncp_reply_dword_hl(conn, 0); 12152153Sbp target->object_type = ncp_reply_word_hl(conn, 4); 12252153Sbp memcpy(target->object_name, ncp_reply_data(conn, 6), 48); 12352153Sbp return 0; 12452153Sbp} 12552153Sbp 12652153Sbpint 12752153Sbpncp_change_obj_passwd(NWCONN_HANDLE connid, 12852153Sbp const struct ncp_bindery_object *object, 12952153Sbp const u_char *key, 13052153Sbp const u_char *oldpasswd, 13152153Sbp const u_char *newpasswd) 13252153Sbp{ 13352153Sbp long id = htonl(object->object_id); 13452153Sbp u_char cryptkey[8]; 13552153Sbp u_char newpwd[16]; /* new passwd as stored by server */ 13652153Sbp u_char oldpwd[16]; /* old passwd as stored by server */ 13752153Sbp u_char len; 13852153Sbp DECLARE_RQ; 13952153Sbp 14052153Sbp memcpy(cryptkey, key, 8); 14152153Sbp nw_keyhash((u_char *)&id, oldpasswd, strlen(oldpasswd), oldpwd); 14252153Sbp nw_keyhash((u_char *)&id, newpasswd, strlen(newpasswd), newpwd); 14352153Sbp nw_encrypt(cryptkey, oldpwd, cryptkey); 14452153Sbp nw_passencrypt(oldpwd, newpwd, newpwd); 14552153Sbp nw_passencrypt(oldpwd + 8, newpwd + 8, newpwd + 8); 14652153Sbp if ((len = strlen(newpasswd)) > 63) { 14752153Sbp len = 63; 14852153Sbp } 14952153Sbp len = ((len ^ oldpwd[0] ^ oldpwd[1]) & 0x7f) | 0x40; 15052153Sbp 15152153Sbp ncp_init_request_s(conn, 75); 15252153Sbp ncp_add_mem(conn, cryptkey, 8); 15352153Sbp ncp_add_word_hl(conn, object->object_type); 15452153Sbp ncp_add_pstring(conn, object->object_name); 15552153Sbp ncp_add_byte(conn, len); 15652153Sbp ncp_add_mem(conn, newpwd, 16); 15752153Sbp return ncp_request(connid, 23, conn); 15852153Sbp} 15952153Sbp 16052153Sbp/* 16152153Sbp * target is a 8-byte buffer 16252153Sbp */ 16352153Sbpint 16452153Sbpncp_get_encryption_key(NWCONN_HANDLE cH, char *target) { 16552153Sbp int error; 16652153Sbp DECLARE_RQ; 16752153Sbp 16852153Sbp ncp_init_request_s(conn, 23); 16952153Sbp 17052153Sbp error = ncp_request(cH, 23, conn); 17152153Sbp if (error) 17252153Sbp return error; 17352153Sbp if (conn->rpsize < 8) 17452153Sbp return EACCES; 17552153Sbp memcpy(target, ncp_reply_data(conn, 0), 8); 17652153Sbp return 0; 17752153Sbp} 17852153Sbp 17952153Sbpint 18052153Sbpncp_keyed_verify_password(NWCONN_HANDLE cH, char *key, char *passwd, 18152704Sbp struct ncp_bindery_object *objinfo) 18252704Sbp{ 18352153Sbp u_long id = htonl(objinfo->object_id); 18452153Sbp u_char cryptkey[8]; 18552153Sbp u_char buf[128]; 18652153Sbp DECLARE_RQ; 18752153Sbp 18852153Sbp nw_keyhash((u_char *)&id, passwd, strlen(passwd), buf); 18952153Sbp nw_encrypt(key, buf, cryptkey); 19052153Sbp 19152153Sbp ncp_init_request_s(conn, 74); 19252153Sbp ncp_add_mem(conn, cryptkey, sizeof(cryptkey)); 19352153Sbp ncp_add_word_hl(conn, objinfo->object_type); 19452153Sbp ncp_add_pstring(conn, objinfo->object_name); 19552153Sbp 19652153Sbp return ncp_request(cH, 23, conn); 19752153Sbp} 19852153Sbp 19952153Sbpstatic char passkeys[256 + 16] = { 20052153Sbp 0x0f, 0x08, 0x05, 0x07, 0x0c, 0x02, 0x0e, 0x09, 20152153Sbp 0x00, 0x01, 0x06, 0x0d, 0x03, 0x04, 0x0b, 0x0a, 20252153Sbp 0x02, 0x0c, 0x0e, 0x06, 0x0f, 0x00, 0x01, 0x08, 20352153Sbp 0x0d, 0x03, 0x0a, 0x04, 0x09, 0x0b, 0x05, 0x07, 20452153Sbp 0x05, 0x02, 0x09, 0x0f, 0x0c, 0x04, 0x0d, 0x00, 20552153Sbp 0x0e, 0x0a, 0x06, 0x08, 0x0b, 0x01, 0x03, 0x07, 20652153Sbp 0x0f, 0x0d, 0x02, 0x06, 0x07, 0x08, 0x05, 0x09, 20752153Sbp 0x00, 0x04, 0x0c, 0x03, 0x01, 0x0a, 0x0b, 0x0e, 20852153Sbp 0x05, 0x0e, 0x02, 0x0b, 0x0d, 0x0a, 0x07, 0x00, 20952153Sbp 0x08, 0x06, 0x04, 0x01, 0x0f, 0x0c, 0x03, 0x09, 21052153Sbp 0x08, 0x02, 0x0f, 0x0a, 0x05, 0x09, 0x06, 0x0c, 21152153Sbp 0x00, 0x0b, 0x01, 0x0d, 0x07, 0x03, 0x04, 0x0e, 21252153Sbp 0x0e, 0x08, 0x00, 0x09, 0x04, 0x0b, 0x02, 0x07, 21352153Sbp 0x0c, 0x03, 0x0a, 0x05, 0x0d, 0x01, 0x06, 0x0f, 21452153Sbp 0x01, 0x04, 0x08, 0x0a, 0x0d, 0x0b, 0x07, 0x0e, 21552153Sbp 0x05, 0x0f, 0x03, 0x09, 0x00, 0x02, 0x06, 0x0c, 21652153Sbp 0x05, 0x03, 0x0c, 0x08, 0x0b, 0x02, 0x0e, 0x0a, 21752153Sbp 0x04, 0x01, 0x0d, 0x00, 0x06, 0x07, 0x0f, 0x09, 21852153Sbp 0x06, 0x00, 0x0b, 0x0e, 0x0d, 0x04, 0x0c, 0x0f, 21952153Sbp 0x07, 0x02, 0x08, 0x0a, 0x01, 0x05, 0x03, 0x09, 22052153Sbp 0x0b, 0x05, 0x0a, 0x0e, 0x0f, 0x01, 0x0c, 0x00, 22152153Sbp 0x06, 0x04, 0x02, 0x09, 0x03, 0x0d, 0x07, 0x08, 22252153Sbp 0x07, 0x02, 0x0a, 0x00, 0x0e, 0x08, 0x0f, 0x04, 22352153Sbp 0x0c, 0x0b, 0x09, 0x01, 0x05, 0x0d, 0x03, 0x06, 22452153Sbp 0x07, 0x04, 0x0f, 0x09, 0x05, 0x01, 0x0c, 0x0b, 22552153Sbp 0x00, 0x03, 0x08, 0x0e, 0x02, 0x0a, 0x06, 0x0d, 22652153Sbp 0x09, 0x04, 0x08, 0x00, 0x0a, 0x03, 0x01, 0x0c, 22752153Sbp 0x05, 0x0f, 0x07, 0x02, 0x0b, 0x0e, 0x06, 0x0d, 22852153Sbp 0x09, 0x05, 0x04, 0x07, 0x0e, 0x08, 0x03, 0x01, 22952153Sbp 0x0d, 0x0b, 0x0c, 0x02, 0x00, 0x0f, 0x06, 0x0a, 23052153Sbp 0x09, 0x0a, 0x0b, 0x0d, 0x05, 0x03, 0x0f, 0x00, 23152153Sbp 0x01, 0x0c, 0x08, 0x07, 0x06, 0x04, 0x0e, 0x02, 23252153Sbp 0x03, 0x0e, 0x0f, 0x02, 0x0d, 0x0c, 0x04, 0x05, 23352153Sbp 0x09, 0x06, 0x00, 0x01, 0x0b, 0x07, 0x0a, 0x08 23452153Sbp}; 23552153Sbp 23652153Sbpstatic void 23752153Sbpnw_passencrypt(char *old, char *new, char *out) 23852153Sbp{ 23952153Sbp char *p, v; 24052153Sbp char copy[8]; 24152153Sbp int i, di, ax; 24252153Sbp 24352153Sbp#define HIGH(x) (((x) >> 4) & 0xf) 24452153Sbp#define LOW(x) ((x) & 0xf) 24552153Sbp memcpy(copy, new, 8); 24652153Sbp 24752153Sbp for (i = 0; i < 16; i++) { 24852153Sbp for (di = 0, ax = 0, p = old; di < 8; di++, ax += 0x20, p++) { 24952153Sbp v = copy[di] ^ *p; 25052153Sbp copy[di] = (passkeys[HIGH(v) + ax + 0x10] << 4) | 25152153Sbp passkeys[LOW(v) + ax]; 25252153Sbp } 25352153Sbp v = old[7]; 25452153Sbp for (p = old + 7; p > old; p--) { 25552153Sbp *p = HIGH(p[-1]) | ((*p) << 4); 25652153Sbp } 25752153Sbp *old = HIGH(v) | (*old) << 4; 25852153Sbp bzero(out, 8); 25952153Sbp 26052153Sbp for (di = 0; di < 16; di++) { 26152153Sbp v = passkeys[di + 0x100]; 26252153Sbp v = (v & 1) ? HIGH(copy[v / 2]) : LOW(copy[v / 2]); 26352153Sbp out[di / 2] |= ((di & 1) ? v << 4 : v); 26452153Sbp } 26552153Sbp memcpy(copy, out, 8); 26652153Sbp } 26752153Sbp} 268