File: apply-patch-for-missing-323-code-in-more-modern-mysql-cli.patch

package info (click to toggle)
pam-mysql 0.8.2-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,220 kB
  • sloc: ansic: 4,535; python: 102; makefile: 31
file content (188 lines) | stat: -rw-r--r-- 8,176 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
From: UnyfiOnGithub <kyrian@ore.org>
Date: Sat, 29 Aug 2020 21:17:13 +0100
Subject: apply patch for missing 323 code in more modern mysql client libs
 and appropriate readme warnings

---
 README                |   5 +++
 compat_323_password.h | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++
 pam_mysql.c           |  20 +++++++++-
 3 files changed, 129 insertions(+), 2 deletions(-)
 create mode 100644 compat_323_password.h

diff --git a/README b/README
index 1408fda..94a61eb 100644
--- a/README
+++ b/README
@@ -144,6 +144,11 @@ use_323_passwd (false)
 
     This option appeared since 0.7pre2 and 0.6.1.
 
+    Note that the code for this to work has been dropped from client libraries
+    for mysql 5.x (or so) onwards, so a workaround has been patched in to
+    pam-mysql. If at all possible you should upgrade your password encryption
+    method instead and not rely on this feature.
+
 where
 
     Additional criteria for the query. For example:
diff --git a/compat_323_password.h b/compat_323_password.h
new file mode 100644
index 0000000..9807d07
--- /dev/null
+++ b/compat_323_password.h
@@ -0,0 +1,106 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+/* password checking routines */
+/*****************************************************************************
+  The main idea is that no password are sent between client & server on
+  connection and that no password are saved in mysql in a decodable form.
+
+  On connection a random string is generated and sent to the client.
+  The client generates a new string with a random generator inited with
+  the hash values from the password and the sent string.
+  This 'check' string is sent to the server where it is compared with
+  a string generated from the stored hash_value of the password and the
+  random string.
+
+  The password is saved (in user.password) by using the PASSWORD() function in
+  mysql.
+
+  This is .c file because it's used in libmysqlclient, which is entirely in C.
+  (we need it to be portable to a variety of systems).
+  Example:
+    update user set password=PASSWORD("hello") where user="test"
+  This saves a hashed number as a string in the password field.
+
+  The new authentication is performed in following manner:
+
+  SERVER:  public_seed=create_random_string()
+           send(public_seed)
+
+  CLIENT:  recv(public_seed)
+           hash_stage1=sha1("password")
+           hash_stage2=sha1(hash_stage1)
+           reply=xor(hash_stage1, sha1(public_seed,hash_stage2)
+
+           // this three steps are done in scramble() 
+
+           send(reply)
+
+     
+  SERVER:  recv(reply)
+           hash_stage1=xor(reply, sha1(public_seed,hash_stage2))
+           candidate_hash2=sha1(hash_stage1)
+           check(candidate_hash2==hash_stage2)
+
+           // this three steps are done in check_scramble()
+
+*****************************************************************************/
+
+
+/*
+    Generate binary hash from raw text string 
+    Used for Pre-4.1 password handling
+  SYNOPSIS
+    hash_password()
+    result       OUT store hash in this location
+    password     IN  plain text password to build hash
+    password_len IN  password length (password may be not null-terminated)
+*/
+
+void compat_323_hash_password(ulong *result, const char *password, uint password_len)
+{
+  register ulong nr=1345345333L, add=7, nr2=0x12345671L;
+  ulong tmp;
+  const char *password_end= password + password_len;
+  for (; password < password_end; password++)
+  {
+    if (*password == ' ' || *password == '\t')
+      continue;                                 /* skip space in password */
+    tmp= (ulong) (unsigned char) *password;
+    nr^= (((nr & 63)+add)*tmp)+ (nr << 8);
+    nr2+=(nr2 << 8) ^ nr;
+    add+=tmp;
+  }
+  result[0]=nr & (((ulong) 1L << 31) -1L); /* Don't use sign bit (str2int) */;
+  result[1]=nr2 & (((ulong) 1L << 31) -1L);
+}
+
+
+/*
+    Create password to be stored in user database from raw string
+    Used for pre-4.1 password handling
+  SYNOPSIS
+    make_scrambled_password_323()
+    to        OUT store scrambled password here
+    password  IN  user-supplied password
+*/
+
+void compat_make_scrambled_password_323(char *to, const char *password)
+{
+  ulong hash_res[2];
+  compat_323_hash_password(hash_res, password, (uint) strlen(password));
+  sprintf(to, "%08lx%08lx", hash_res[0], hash_res[1]);
+}
diff --git a/pam_mysql.c b/pam_mysql.c
index f4dac29..593f4ca 100644
--- a/pam_mysql.c
+++ b/pam_mysql.c
@@ -3724,12 +3724,20 @@ static pam_mysql_err_t pam_mysql_check_passwd(pam_mysql_ctx_t *ctx,
                                 char buf[42];
 #ifdef HAVE_MAKE_SCRAMBLED_PASSWORD_323
                                 if (ctx->use_323_passwd) {
+                                    syslog(LOG_DEBUG, PAM_MYSQL_LOG_PREFIX "use_323_passwd defined and enabled in pam_mysql_check_passwd");
                                     make_scrambled_password_323(buf, passwd);
                                 } else {
+                                    syslog(LOG_DEBUG, PAM_MYSQL_LOG_PREFIX "use_323_passwd defined and not enabled in pam_mysql_check_passwd");
                                     make_scrambled_password(buf, passwd);
                                 }
 #else
-                                make_scrambled_password(buf, passwd);
+                                if (ctx->use_323_passwd) {
+                                    syslog(LOG_WARNING, PAM_MYSQL_LOG_PREFIX "Workaround applied. use_323_passwd not defined but use attempted in pam_mysql_check_passwd");
+                                    compat_make_scrambled_password_323(buf, passwd);
+                                } else {
+                                    syslog(LOG_DEBUG, PAM_MYSQL_LOG_PREFIX "use_323_passwd not defined and use not attempted in pam_mysql_check_passwd");
+                                    make_scrambled_password(buf, passwd);
+                                }
 #endif
 
                                 vresult = strcmp(row[0], buf);
@@ -4048,12 +4056,20 @@ static pam_mysql_err_t pam_mysql_update_passwd(pam_mysql_ctx_t *ctx, const char
                     }
 #ifdef HAVE_MAKE_SCRAMBLED_PASSWORD_323
                     if (ctx->use_323_passwd) {
+                        syslog(LOG_DEBUG, PAM_MYSQL_LOG_PREFIX "use_323_passwd defined and enabled in pam_mysql_update_passwd");
                         make_scrambled_password_323(encrypted_passwd, new_passwd);
                     } else {
+                        syslog(LOG_DEBUG, PAM_MYSQL_LOG_PREFIX "use_323_passwd defined and not enabled in pam_mysql_update_passwd");
                         make_scrambled_password(encrypted_passwd, new_passwd);
                     }
 #else
-                    make_scrambled_password(encrypted_passwd, new_passwd);
+                    if (ctx->use_323_passwd) {
+                        syslog(LOG_WARNING, PAM_MYSQL_LOG_PREFIX "Workaround applied. use_323_passwd not defined but use attempted in pam_mysql_update_passwd");
+                        compat_make_scrambled_password_323(encrypted_passwd, new_passwd);
+                    } else {
+                        syslog(LOG_DEBUG, PAM_MYSQL_LOG_PREFIX "use_323_passwd not defined and use not attempted in pam_mysql_update_passwd");
+                        make_scrambled_password(encrypted_passwd, new_passwd);
+                    }
 #endif
                     break;