route.8: Remove NS remains.
[dragonfly.git] / lib / libncp / ncpl_bind.c
1 /*
2  * Copyright (c) 1999, Boris Popov
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *    This product includes software developed by Boris Popov.
16  * 4. Neither the name of the author nor the names of any co-contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  * $FreeBSD: src/lib/libncp/ncpl_bind.c,v 1.2 1999/10/31 03:39:03 bp Exp $
33  * $DragonFly: src/lib/libncp/ncpl_bind.c,v 1.2 2003/06/17 04:26:50 dillon Exp $
34  */
35 #include <sys/types.h>
36 #include <errno.h>
37 #include <string.h>
38 #include <netncp/ncp_lib.h>
39
40 static void nw_passencrypt(char *old, char *new, char *out);
41
42 int
43 ncp_get_bindery_object_id(NWCONN_HANDLE connid, u_int16_t object_type,
44         const char *object_name, struct ncp_bindery_object *target)
45 {
46         int error;
47         DECLARE_RQ;
48
49         ncp_init_request_s(conn, 53);
50         ncp_add_word_hl(conn, object_type);
51         ncp_add_pstring(conn, object_name);
52
53         if ((error = ncp_request(connid, 23, conn)) != 0) {
54                 return error;
55         }
56         if (conn->rpsize < 54) {
57                 return EACCES;
58         }
59         target->object_id = ncp_reply_dword_hl(conn, 0);
60         target->object_type = ncp_reply_word_hl(conn, 4);
61         memcpy(target->object_name, ncp_reply_data(conn, 6), 48);
62         return 0;
63 }
64
65 int
66 ncp_read_property_value(NWCONN_HANDLE connid, int object_type,
67         const char *object_name, int segment, const char *prop_name,
68         struct nw_property *target)
69 {
70         int error;
71         struct ncp_buf conn;
72         ncp_init_request_s(&conn, 61);
73         ncp_add_word_hl(&conn, object_type);
74         ncp_add_pstring(&conn, object_name);
75         ncp_add_byte(&conn, segment);
76         ncp_add_pstring(&conn, prop_name);
77
78         if ((error = ncp_request(connid,23,&conn)) != 0) {
79                 return error;
80         }
81         memcpy(&(target->value), ncp_reply_data(&conn, 0), 128);
82         target->more_flag = ncp_reply_byte(&conn, 128);
83         target->property_flag = ncp_reply_byte(&conn, 129);
84         return 0;
85 }
86
87 int
88 ncp_scan_bindery_object(NWCONN_HANDLE connid, u_int32_t last_id,
89         u_int16_t object_type, char *search_string,
90         struct ncp_bindery_object *target)
91 {
92         int error;
93         DECLARE_RQ;
94
95         ncp_init_request_s(conn, 55);
96         ncp_add_dword_hl(conn, last_id);
97         ncp_add_word_hl(conn, object_type);
98         ncp_add_pstring(conn, search_string);
99         error = ncp_request(connid, 23, conn);
100         if (error) return error;
101         target->object_id = ncp_reply_dword_hl(conn, 0);
102         target->object_type = ncp_reply_word_hl(conn, 4);
103         memcpy(target->object_name, ncp_reply_data(conn, 6),NCP_BINDERY_NAME_LEN);
104         target->object_flags = ncp_reply_byte(conn, 54);
105         target->object_security = ncp_reply_byte(conn, 55);
106         target->object_has_prop = ncp_reply_byte(conn, 56);
107         return 0;
108 }
109
110 int
111 ncp_get_bindery_object_name(NWCONN_HANDLE connid, u_int32_t object_id,
112         struct ncp_bindery_object *target)
113 {
114         int error;
115         DECLARE_RQ;
116
117         ncp_init_request_s(conn, 54);
118         ncp_add_dword_hl(conn, object_id);
119         if ((error = ncp_request(connid, 23, conn)) != 0)
120                 return error;
121         target->object_id = ncp_reply_dword_hl(conn, 0);
122         target->object_type = ncp_reply_word_hl(conn, 4);
123         memcpy(target->object_name, ncp_reply_data(conn, 6), 48);
124         return 0;
125 }
126
127 int
128 ncp_change_obj_passwd(NWCONN_HANDLE connid, 
129         const struct ncp_bindery_object *object,
130         const u_char *key,
131         const u_char *oldpasswd,
132         const u_char *newpasswd)
133 {
134         long id = htonl(object->object_id);
135         u_char cryptkey[8];
136         u_char newpwd[16];      /* new passwd as stored by server */
137         u_char oldpwd[16];      /* old passwd as stored by server */
138         u_char len;
139         DECLARE_RQ;
140
141         memcpy(cryptkey, key, 8);
142         nw_keyhash((u_char *)&id, oldpasswd, strlen(oldpasswd), oldpwd);
143         nw_keyhash((u_char *)&id, newpasswd, strlen(newpasswd), newpwd);
144         nw_encrypt(cryptkey, oldpwd, cryptkey);
145         nw_passencrypt(oldpwd, newpwd, newpwd);
146         nw_passencrypt(oldpwd + 8, newpwd + 8, newpwd + 8);
147         if ((len = strlen(newpasswd)) > 63) {
148                 len = 63;
149         }
150         len = ((len ^ oldpwd[0] ^ oldpwd[1]) & 0x7f) | 0x40;
151
152         ncp_init_request_s(conn, 75);
153         ncp_add_mem(conn, cryptkey, 8);
154         ncp_add_word_hl(conn, object->object_type);
155         ncp_add_pstring(conn, object->object_name);
156         ncp_add_byte(conn, len);
157         ncp_add_mem(conn, newpwd, 16);
158         return ncp_request(connid, 23, conn);
159 }
160
161 /*
162  * target is a 8-byte buffer
163  */
164 int
165 ncp_get_encryption_key(NWCONN_HANDLE cH, char *target) {
166         int error;
167         DECLARE_RQ;
168
169         ncp_init_request_s(conn, 23);
170
171         error = ncp_request(cH, 23, conn);
172         if (error)
173                 return error;
174         if (conn->rpsize < 8)
175                 return EACCES;
176         memcpy(target, ncp_reply_data(conn, 0), 8);
177         return 0;
178 }
179
180 int
181 ncp_keyed_verify_password(NWCONN_HANDLE cH, char *key, char *passwd,
182         struct ncp_bindery_object *objinfo)
183 {
184         u_long id = htonl(objinfo->object_id);
185         u_char cryptkey[8];
186         u_char buf[128];
187         DECLARE_RQ;
188
189         nw_keyhash((u_char *)&id, passwd, strlen(passwd), buf);
190         nw_encrypt(key, buf, cryptkey);
191
192         ncp_init_request_s(conn, 74);
193         ncp_add_mem(conn, cryptkey, sizeof(cryptkey));
194         ncp_add_word_hl(conn, objinfo->object_type);
195         ncp_add_pstring(conn, objinfo->object_name);
196
197         return ncp_request(cH, 23, conn);
198 }
199
200 static char passkeys[256 + 16] = {
201         0x0f, 0x08, 0x05, 0x07, 0x0c, 0x02, 0x0e, 0x09,
202         0x00, 0x01, 0x06, 0x0d, 0x03, 0x04, 0x0b, 0x0a,
203         0x02, 0x0c, 0x0e, 0x06, 0x0f, 0x00, 0x01, 0x08,
204         0x0d, 0x03, 0x0a, 0x04, 0x09, 0x0b, 0x05, 0x07,
205         0x05, 0x02, 0x09, 0x0f, 0x0c, 0x04, 0x0d, 0x00,
206         0x0e, 0x0a, 0x06, 0x08, 0x0b, 0x01, 0x03, 0x07,
207         0x0f, 0x0d, 0x02, 0x06, 0x07, 0x08, 0x05, 0x09,
208         0x00, 0x04, 0x0c, 0x03, 0x01, 0x0a, 0x0b, 0x0e,
209         0x05, 0x0e, 0x02, 0x0b, 0x0d, 0x0a, 0x07, 0x00,
210         0x08, 0x06, 0x04, 0x01, 0x0f, 0x0c, 0x03, 0x09,
211         0x08, 0x02, 0x0f, 0x0a, 0x05, 0x09, 0x06, 0x0c,
212         0x00, 0x0b, 0x01, 0x0d, 0x07, 0x03, 0x04, 0x0e,
213         0x0e, 0x08, 0x00, 0x09, 0x04, 0x0b, 0x02, 0x07,
214         0x0c, 0x03, 0x0a, 0x05, 0x0d, 0x01, 0x06, 0x0f,
215         0x01, 0x04, 0x08, 0x0a, 0x0d, 0x0b, 0x07, 0x0e,
216         0x05, 0x0f, 0x03, 0x09, 0x00, 0x02, 0x06, 0x0c,
217         0x05, 0x03, 0x0c, 0x08, 0x0b, 0x02, 0x0e, 0x0a,
218         0x04, 0x01, 0x0d, 0x00, 0x06, 0x07, 0x0f, 0x09,
219         0x06, 0x00, 0x0b, 0x0e, 0x0d, 0x04, 0x0c, 0x0f,
220         0x07, 0x02, 0x08, 0x0a, 0x01, 0x05, 0x03, 0x09,
221         0x0b, 0x05, 0x0a, 0x0e, 0x0f, 0x01, 0x0c, 0x00,
222         0x06, 0x04, 0x02, 0x09, 0x03, 0x0d, 0x07, 0x08,
223         0x07, 0x02, 0x0a, 0x00, 0x0e, 0x08, 0x0f, 0x04,
224         0x0c, 0x0b, 0x09, 0x01, 0x05, 0x0d, 0x03, 0x06,
225         0x07, 0x04, 0x0f, 0x09, 0x05, 0x01, 0x0c, 0x0b,
226         0x00, 0x03, 0x08, 0x0e, 0x02, 0x0a, 0x06, 0x0d,
227         0x09, 0x04, 0x08, 0x00, 0x0a, 0x03, 0x01, 0x0c,
228         0x05, 0x0f, 0x07, 0x02, 0x0b, 0x0e, 0x06, 0x0d,
229         0x09, 0x05, 0x04, 0x07, 0x0e, 0x08, 0x03, 0x01,
230         0x0d, 0x0b, 0x0c, 0x02, 0x00, 0x0f, 0x06, 0x0a,
231         0x09, 0x0a, 0x0b, 0x0d, 0x05, 0x03, 0x0f, 0x00,
232         0x01, 0x0c, 0x08, 0x07, 0x06, 0x04, 0x0e, 0x02,
233         0x03, 0x0e, 0x0f, 0x02, 0x0d, 0x0c, 0x04, 0x05,
234         0x09, 0x06, 0x00, 0x01, 0x0b, 0x07, 0x0a, 0x08
235 };
236
237 static void
238 nw_passencrypt(char *old, char *new, char *out)
239 {
240         char *p, v;
241         char copy[8];
242         int i, di, ax;
243
244 #define HIGH(x) (((x) >> 4) & 0xf)
245 #define LOW(x)  ((x) & 0xf)
246         memcpy(copy, new, 8);
247
248         for (i = 0; i < 16; i++) {
249                 for (di = 0, ax = 0, p = old; di < 8; di++, ax += 0x20, p++) {
250                         v = copy[di] ^ *p;
251                         copy[di] = (passkeys[HIGH(v) + ax + 0x10] << 4) |
252                                    passkeys[LOW(v) + ax];
253                 }
254                 v = old[7];
255                 for (p = old + 7; p > old; p--) {
256                         *p = HIGH(p[-1]) | ((*p) << 4);
257                 }
258                 *old = HIGH(v) | (*old) << 4;
259                 bzero(out, 8);
260
261                 for (di = 0; di < 16; di++) {
262                         v = passkeys[di + 0x100];
263                         v = (v & 1) ? HIGH(copy[v / 2]) : LOW(copy[v / 2]);
264                         out[di / 2] |= ((di & 1) ? v << 4 : v);
265                 }
266                 memcpy(copy, out, 8);
267         }
268 }