]>
Commit | Line | Data |
---|---|---|
04e4e140 | 1 | /* |
5b74111a | 2 | * Copyright (C) 1996-2018 The Squid Software Foundation and contributors |
04e4e140 AJ |
3 | * |
4 | * Squid software is distributed under GPLv2+ license and includes | |
5 | * contributions from numerous individuals and organizations. | |
6 | * Please see the COPYING and CONTRIBUTORS files for details. | |
7 | */ | |
7c16470c | 8 | |
26ac0430 | 9 | /* |
94439e4e | 10 | * Unix SMB/Netbios implementation. |
11 | * Version 1.9. | |
12 | * SMB parameters and setup | |
13 | * Copyright (C) Andrew Tridgell 1992-1997 | |
14 | * Modified by Jeremy Allison 1995. | |
04e4e140 AJ |
15 | */ |
16 | ||
17 | /* | |
94439e4e | 18 | * This program is free software; you can redistribute it and/or modify |
19 | * it under the terms of the GNU General Public License as published by | |
20 | * the Free Software Foundation; either version 2 of the License, or | |
21 | * (at your option) any later version. | |
26ac0430 | 22 | * |
94439e4e | 23 | * This program is distributed in the hope that it will be useful, |
24 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
25 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
26 | * GNU General Public License for more details. | |
26ac0430 | 27 | * |
94439e4e | 28 | * You should have received a copy of the GNU General Public License |
29 | * along with this program; if not, write to the Free Software | |
30 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
31 | */ | |
32 | ||
04e4e140 AJ |
33 | #include "squid.h" |
34 | ||
94439e4e | 35 | #include <string.h> |
36 | #include <sys/types.h> | |
37 | #include <sys/socket.h> | |
38 | #include <netinet/in.h> | |
39 | #include <arpa/inet.h> | |
40 | #include <dirent.h> | |
41 | #include <string.h> | |
42 | #include <ctype.h> | |
6d73604c | 43 | |
44 | /* AI inclusion for Solaris filesystem */ | |
45 | #ifdef SOLARIS | |
46 | #include <sys/vfs.h> | |
47 | #endif | |
94439e4e | 48 | |
7c16470c | 49 | #include "smblib/smblib-priv.h" |
94439e4e | 50 | #define uchar unsigned char |
94439e4e | 51 | |
7c16470c | 52 | #include "rfcnb/byteorder.h" |
94439e4e | 53 | |
7c16470c AJ |
54 | #include "smblib/md4.h" |
55 | #include "smblib/smbdes.h" | |
56 | #include "smblib/smbencrypt.h" | |
94439e4e | 57 | |
c06f9773 | 58 | static void E_md4hash(unsigned char *passwd, unsigned char *p16); |
59 | static char *StrnCpy(char *dest, char *src, int n); | |
60 | static void strupper(char *s); | |
94439e4e | 61 | |
62 | /* | |
63 | * This implements the X/Open SMB password encryption | |
26ac0430 | 64 | * It takes a password, a 8 byte "crypt key" and puts 24 bytes of |
94439e4e | 65 | * encrypted password into p24 */ |
66 | void | |
67 | SMBencrypt(uchar * passwd, uchar * c8, uchar * p24) | |
68 | { | |
69 | uchar p14[15], p21[21]; | |
70 | ||
71 | memset(p21, '\0', 21); | |
72 | memset(p14, '\0', 14); | |
73 | StrnCpy((char *) p14, (char *) passwd, 14); | |
74 | ||
75 | strupper((char *) p14); | |
76 | E_P16(p14, p21); | |
77 | E_P24(p21, c8, p24); | |
78 | } | |
79 | ||
80 | /* Routines for Windows NT MD4 Hash functions. */ | |
81 | static int | |
7c16470c | 82 | _my_wcslen(int16_t * str) |
94439e4e | 83 | { |
84 | int len = 0; | |
85 | while (*str++ != 0) | |
26ac0430 | 86 | len++; |
94439e4e | 87 | return len; |
88 | } | |
89 | ||
90 | /* | |
91 | * Convert a string into an NT UNICODE string. | |
26ac0430 | 92 | * Note that regardless of processor type |
94439e4e | 93 | * this must be in intel (little-endian) |
94 | * format. | |
95 | */ | |
96 | ||
97 | static int | |
7c16470c | 98 | _my_mbstowcs(int16_t * dst, uchar * src, int len) |
94439e4e | 99 | { |
100 | int i; | |
7c16470c | 101 | int16_t val; |
94439e4e | 102 | |
103 | for (i = 0; i < len; i++) { | |
26ac0430 AJ |
104 | val = *src; |
105 | SSVAL(dst, 0, val); | |
106 | dst++; | |
107 | src++; | |
108 | if (val == 0) | |
109 | break; | |
94439e4e | 110 | } |
111 | return i; | |
112 | } | |
113 | ||
26ac0430 | 114 | /* |
94439e4e | 115 | * Creates the MD4 Hash of the users password in NT UNICODE. |
116 | */ | |
117 | ||
118 | void | |
119 | E_md4hash(uchar * passwd, uchar * p16) | |
120 | { | |
121 | int len; | |
7c16470c | 122 | int16_t wpwd[129]; |
94439e4e | 123 | |
124 | /* Password cannot be longer than 128 characters */ | |
125 | len = strlen((char *) passwd); | |
126 | if (len > 128) | |
26ac0430 | 127 | len = 128; |
94439e4e | 128 | /* Password must be converted to NT unicode */ |
129 | _my_mbstowcs(wpwd, passwd, len); | |
f53969cc | 130 | wpwd[len] = 0; /* Ensure string is null terminated */ |
94439e4e | 131 | /* Calculate length in bytes */ |
7c16470c | 132 | len = _my_wcslen(wpwd) * sizeof(int16_t); |
94439e4e | 133 | |
134 | mdfour(p16, (unsigned char *) wpwd, len); | |
135 | } | |
136 | ||
137 | /* Does the NT MD4 hash then des encryption. */ | |
138 | ||
139 | void | |
140 | SMBNTencrypt(uchar * passwd, uchar * c8, uchar * p24) | |
141 | { | |
142 | uchar p21[21]; | |
143 | ||
144 | memset(p21, '\0', 21); | |
145 | ||
146 | E_md4hash(passwd, p21); | |
147 | E_P24(p21, c8, p24); | |
148 | } | |
149 | ||
150 | /* Does both the NT and LM owfs of a user's password */ | |
151 | ||
152 | void | |
153 | nt_lm_owf_gen(char *pwd, char *nt_p16, char *p16) | |
154 | { | |
155 | char passwd[130]; | |
156 | StrnCpy(passwd, pwd, sizeof(passwd) - 1); | |
157 | ||
158 | /* Calculate the MD4 hash (NT compatible) of the password */ | |
159 | memset(nt_p16, '\0', 16); | |
160 | E_md4hash((uchar *) passwd, (uchar *) nt_p16); | |
161 | ||
162 | /* Mangle the passwords into Lanman format */ | |
163 | passwd[14] = '\0'; | |
164 | strupper(passwd); | |
165 | ||
166 | /* Calculate the SMB (lanman) hash functions of the password */ | |
167 | ||
168 | memset(p16, '\0', 16); | |
169 | E_P16((uchar *) passwd, (uchar *) p16); | |
170 | ||
171 | /* clear out local copy of user's password (just being paranoid). */ | |
04830959 | 172 | memset(passwd, 0, sizeof(passwd)); |
94439e4e | 173 | } |
174 | ||
175 | /**************************************************************************** | |
176 | line strncpy but always null terminates. Make sure there is room! | |
177 | ****************************************************************************/ | |
178 | char * | |
179 | StrnCpy(char *dest, char *src, int n) | |
180 | { | |
181 | char *d = dest; | |
182 | if (!dest) | |
26ac0430 | 183 | return (NULL); |
94439e4e | 184 | if (!src) { |
26ac0430 AJ |
185 | *dest = 0; |
186 | return (dest); | |
94439e4e | 187 | } |
188 | while (n-- && (*d++ = *src++)); | |
189 | *d = 0; | |
190 | return (dest); | |
191 | } | |
192 | ||
193 | void | |
194 | strupper(char *s) | |
195 | { | |
196 | while (*s) { | |
197 | #if UNUSED_CODE | |
198 | #if !defined(KANJI_WIN95_COMPATIBILITY) | |
26ac0430 AJ |
199 | if (lp_client_code_page() == KANJI_CODEPAGE) { |
200 | ||
201 | if (is_shift_jis(*s)) { | |
202 | if (is_sj_lower(s[0], s[1])) | |
203 | s[1] = sj_toupper2(s[1]); | |
204 | s += 2; | |
205 | } else if (is_kana(*s)) { | |
206 | s++; | |
207 | } else { | |
208 | if (islower((int)(unsigned char)*s)) | |
209 | *s = toupper((int)(unsigned char)*s); | |
210 | s++; | |
211 | } | |
212 | } else | |
94439e4e | 213 | #endif /* KANJI_WIN95_COMPATIBILITY */ |
214 | #endif /* UNUSED_CODE */ | |
26ac0430 AJ |
215 | { |
216 | if (islower((int)(unsigned char)*s)) | |
217 | *s = toupper((int)(unsigned char)*s); | |
218 | s++; | |
219 | } | |
94439e4e | 220 | } |
221 | } | |
f53969cc | 222 |