]> git.ipfire.org Git - thirdparty/squid.git/blob - lib/smblib/smbencrypt.c
Source Format Enforcement (#532)
[thirdparty/squid.git] / lib / smblib / smbencrypt.c
1 /*
2 * Copyright (C) 1996-2020 The Squid Software Foundation and contributors
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 */
8
9 /*
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.
15 */
16
17 /*
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.
22 *
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.
27 *
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
33 #include "squid.h"
34
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>
43
44 /* AI inclusion for Solaris filesystem */
45 #ifdef SOLARIS
46 #include <sys/vfs.h>
47 #endif
48
49 #include "smblib/smblib-priv.h"
50 #define uchar unsigned char
51
52 #include "rfcnb/byteorder.h"
53
54 #include "smblib/md4.h"
55 #include "smblib/smbdes.h"
56 #include "smblib/smbencrypt.h"
57
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);
61
62 /*
63 * This implements the X/Open SMB password encryption
64 * It takes a password, a 8 byte "crypt key" and puts 24 bytes of
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
82 _my_wcslen(int16_t * str)
83 {
84 int len = 0;
85 while (*str++ != 0)
86 len++;
87 return len;
88 }
89
90 /*
91 * Convert a string into an NT UNICODE string.
92 * Note that regardless of processor type
93 * this must be in intel (little-endian)
94 * format.
95 */
96
97 static int
98 _my_mbstowcs(int16_t * dst, uchar * src, int len)
99 {
100 int i;
101 int16_t val;
102
103 for (i = 0; i < len; i++) {
104 val = *src;
105 SSVAL(dst, 0, val);
106 dst++;
107 src++;
108 if (val == 0)
109 break;
110 }
111 return i;
112 }
113
114 /*
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;
122 int16_t wpwd[129];
123
124 /* Password cannot be longer than 128 characters */
125 len = strlen((char *) passwd);
126 if (len > 128)
127 len = 128;
128 /* Password must be converted to NT unicode */
129 _my_mbstowcs(wpwd, passwd, len);
130 wpwd[len] = 0; /* Ensure string is null terminated */
131 /* Calculate length in bytes */
132 len = _my_wcslen(wpwd) * sizeof(int16_t);
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). */
172 memset(passwd, 0, sizeof(passwd));
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)
183 return (NULL);
184 if (!src) {
185 *dest = 0;
186 return (dest);
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)
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
213 #endif /* KANJI_WIN95_COMPATIBILITY */
214 #endif /* UNUSED_CODE */
215 {
216 if (islower((int)(unsigned char)*s))
217 *s = toupper((int)(unsigned char)*s);
218 s++;
219 }
220 }
221 }
222