Merge ~3v1n0/ubuntu/+source/openssh:ubuntu/devel into ubuntu/+source/openssh:ubuntu/devel

Proposed by Marco Trevisan (Treviño)
Status: Merged
Merged at revision: 8edf97430e2d0a5cdd6307ddea91206f335f1488
Proposed branch: ~3v1n0/ubuntu/+source/openssh:ubuntu/devel
Merge into: ubuntu/+source/openssh:ubuntu/devel
Diff against target: 426 lines (+388/-0)
6 files modified
debian/patches/auth-Add-KbdintResult-definition-to-define-result-values-.patch (+106/-0)
debian/patches/auth-pam-Add-an-enum-to-define-the-PAM-done-status.patch (+73/-0)
debian/patches/auth-pam-Add-debugging-information-when-we-receive-PAM-me.patch (+23/-0)
debian/patches/auth-pam-Immediately-report-interactive-instructions-to-c.patch (+73/-0)
debian/patches/series (+5/-0)
debian/patches/sshconnect2-Write-kbd-interactive-service-info-and-instru.patch (+108/-0)
Reviewer Review Type Date Requested Status
Julian Andres Klode (community) Approve
Tobias Heider (community) Approve
Canonical Server Reporter Pending
git-ubuntu import Pending
Review via email: mp+460160@code.launchpad.net

Description of the change

Cherry-pick upstream proposed and partially approved patches (one maintainer already did, but we need the final merge) [1] to fix usage of SSHd and ssh client with PAM modules that use interactive messages and requests.

[1] https://github.com/openssh/openssh-portable/pull/452

To post a comment you must log in.
Revision history for this message
Tobias Heider (tobhe) :
review: Approve
Revision history for this message
Julian Andres Klode (juliank) wrote :

This is a bit awkward because it has no changelog but I semi-sponsored it with my signoff line

review: Approve
Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote (last edit ):

Julian, I didn't add the changelog because I wasn't sure how the team manages it. For example in desktop, we generate it at upload time using gbp dch, so I was thinking the uploader would have done the same.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/patches/auth-Add-KbdintResult-definition-to-define-result-values-.patch b/debian/patches/auth-Add-KbdintResult-definition-to-define-result-values-.patch
2new file mode 100644
3index 0000000..90880ec
4--- /dev/null
5+++ b/debian/patches/auth-Add-KbdintResult-definition-to-define-result-values-.patch
6@@ -0,0 +1,106 @@
7+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
8+Date: Tue, 17 Oct 2023 04:04:13 +0200
9+Subject: auth: Add KbdintResult definition to define result values explicitly
10+
11+kbdint result vfunc may return various values, so use an enum to make it
12+clearer what each result means without having to dig into the struct
13+documentation.
14+
15+Origin: https://github.com/openssh/openssh-portable/pull/452
16+---
17+ auth-bsdauth.c | 2 +-
18+ auth-pam.c | 10 +++++-----
19+ auth.h | 5 +++++
20+ auth2-chall.c | 4 ++--
21+ 4 files changed, 13 insertions(+), 8 deletions(-)
22+
23+diff --git a/auth-bsdauth.c b/auth-bsdauth.c
24+index d124e99..ca41735 100644
25+--- a/auth-bsdauth.c
26++++ b/auth-bsdauth.c
27+@@ -111,7 +111,7 @@ bsdauth_respond(void *ctx, u_int numresponses, char **responses)
28+ authctxt->as = NULL;
29+ debug3("bsdauth_respond: <%s> = <%d>", responses[0], authok);
30+
31+- return (authok == 0) ? -1 : 0;
32++ return (authok == 0) ? KbdintResultFailure : KbdintResultSuccess;
33+ }
34+
35+ static void
36+diff --git a/auth-pam.c b/auth-pam.c
37+index b49d415..86137a1 100644
38+--- a/auth-pam.c
39++++ b/auth-pam.c
40+@@ -990,15 +990,15 @@ sshpam_respond(void *ctx, u_int num, char **resp)
41+ switch (ctxt->pam_done) {
42+ case 1:
43+ sshpam_authenticated = 1;
44+- return (0);
45++ return KbdintResultSuccess;
46+ case 0:
47+ break;
48+ default:
49+- return (-1);
50++ return KbdintResultFailure;
51+ }
52+ if (num != 1) {
53+ error("PAM: expected one response, got %u", num);
54+- return (-1);
55++ return KbdintResultFailure;
56+ }
57+ if ((buffer = sshbuf_new()) == NULL)
58+ fatal("%s: sshbuf_new failed", __func__);
59+@@ -1015,10 +1015,10 @@ sshpam_respond(void *ctx, u_int num, char **resp)
60+ }
61+ if (ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, buffer) == -1) {
62+ sshbuf_free(buffer);
63+- return (-1);
64++ return KbdintResultFailure;
65+ }
66+ sshbuf_free(buffer);
67+- return (1);
68++ return KbdintResultAgain;
69+ }
70+
71+ static void
72+diff --git a/auth.h b/auth.h
73+index d16dc66..0f1ae29 100644
74+--- a/auth.h
75++++ b/auth.h
76+@@ -51,6 +51,7 @@ struct sshauthopt;
77+ typedef struct Authctxt Authctxt;
78+ typedef struct Authmethod Authmethod;
79+ typedef struct KbdintDevice KbdintDevice;
80++typedef int KbdintResult;
81+
82+ struct Authctxt {
83+ sig_atomic_t success;
84+@@ -112,6 +113,10 @@ struct Authmethod {
85+ int *enabled;
86+ };
87+
88++#define KbdintResultFailure -1
89++#define KbdintResultSuccess 0
90++#define KbdintResultAgain 1
91++
92+ /*
93+ * Keyboard interactive device:
94+ * init_ctx returns: non NULL upon success
95+diff --git a/auth2-chall.c b/auth2-chall.c
96+index 021df82..047d4e8 100644
97+--- a/auth2-chall.c
98++++ b/auth2-chall.c
99+@@ -331,11 +331,11 @@ input_userauth_info_response(int type, u_int32_t seq, struct ssh *ssh)
100+ free(response);
101+
102+ switch (res) {
103+- case 0:
104++ case KbdintResultSuccess:
105+ /* Success! */
106+ authenticated = authctxt->valid ? 1 : 0;
107+ break;
108+- case 1:
109++ case KbdintResultAgain:
110+ /* Authentication needs further interaction */
111+ if (send_userauth_info_request(ssh) == 1)
112+ authctxt->postponed = 1;
113diff --git a/debian/patches/auth-pam-Add-an-enum-to-define-the-PAM-done-status.patch b/debian/patches/auth-pam-Add-an-enum-to-define-the-PAM-done-status.patch
114new file mode 100644
115index 0000000..8deffea
116--- /dev/null
117+++ b/debian/patches/auth-pam-Add-an-enum-to-define-the-PAM-done-status.patch
118@@ -0,0 +1,73 @@
119+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
120+Date: Mon, 16 Oct 2023 21:15:45 +0200
121+Subject: auth-pam: Add an enum to define the PAM done status
122+
123+Makes things more readable and easier to extend
124+
125+Origin: https://github.com/openssh/openssh-portable/pull/452
126+---
127+ auth-pam.c | 17 +++++++++++------
128+ 1 file changed, 11 insertions(+), 6 deletions(-)
129+
130+diff --git a/auth-pam.c b/auth-pam.c
131+index 86137a1..2129163 100644
132+--- a/auth-pam.c
133++++ b/auth-pam.c
134+@@ -136,11 +136,16 @@ typedef pid_t sp_pthread_t;
135+ #define pthread_join fake_pthread_join
136+ #endif
137+
138++typedef int SshPamDone;
139++#define SshPamError -1
140++#define SshPamNone 0
141++#define SshPamAuthenticated 1
142++
143+ struct pam_ctxt {
144+ sp_pthread_t pam_thread;
145+ int pam_psock;
146+ int pam_csock;
147+- int pam_done;
148++ SshPamDone pam_done;
149+ };
150+
151+ static void sshpam_free_ctx(void *);
152+@@ -904,7 +909,7 @@ sshpam_query(void *ctx, char **name, char **info,
153+ **prompts = NULL;
154+ *num = 0;
155+ **echo_on = 0;
156+- ctxt->pam_done = -1;
157++ ctxt->pam_done = SshPamError;
158+ free(msg);
159+ sshbuf_free(buffer);
160+ return 0;
161+@@ -931,7 +936,7 @@ sshpam_query(void *ctx, char **name, char **info,
162+ import_environments(buffer);
163+ *num = 0;
164+ **echo_on = 0;
165+- ctxt->pam_done = 1;
166++ ctxt->pam_done = SshPamAuthenticated;
167+ free(msg);
168+ sshbuf_free(buffer);
169+ return (0);
170+@@ -944,7 +949,7 @@ sshpam_query(void *ctx, char **name, char **info,
171+ *num = 0;
172+ **echo_on = 0;
173+ free(msg);
174+- ctxt->pam_done = -1;
175++ ctxt->pam_done = SshPamError;
176+ sshbuf_free(buffer);
177+ return (-1);
178+ }
179+@@ -988,10 +993,10 @@ sshpam_respond(void *ctx, u_int num, char **resp)
180+
181+ debug2("PAM: %s entering, %u responses", __func__, num);
182+ switch (ctxt->pam_done) {
183+- case 1:
184++ case SshPamAuthenticated:
185+ sshpam_authenticated = 1;
186+ return KbdintResultSuccess;
187+- case 0:
188++ case SshPamNone:
189+ break;
190+ default:
191+ return KbdintResultFailure;
192diff --git a/debian/patches/auth-pam-Add-debugging-information-when-we-receive-PAM-me.patch b/debian/patches/auth-pam-Add-debugging-information-when-we-receive-PAM-me.patch
193new file mode 100644
194index 0000000..ea7fe20
195--- /dev/null
196+++ b/debian/patches/auth-pam-Add-debugging-information-when-we-receive-PAM-me.patch
197@@ -0,0 +1,23 @@
198+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
199+Date: Tue, 17 Oct 2023 04:35:17 +0200
200+Subject: auth-pam: Add debugging information when we receive PAM messages
201+
202+Origin: https://github.com/openssh/openssh-portable/pull/452
203+---
204+ auth-pam.c | 3 +++
205+ 1 file changed, 3 insertions(+)
206+
207+diff --git a/auth-pam.c b/auth-pam.c
208+index 2129163..7a72e72 100644
209+--- a/auth-pam.c
210++++ b/auth-pam.c
211+@@ -450,6 +450,9 @@ sshpam_thread_conv(int n, sshpam_const struct pam_message **msg,
212+ break;
213+ case PAM_ERROR_MSG:
214+ case PAM_TEXT_INFO:
215++ debug3("PAM: Got message of type %d: %s",
216++ PAM_MSG_MEMBER(msg, i, msg_style),
217++ PAM_MSG_MEMBER(msg, i, msg));
218+ if ((r = sshbuf_put_cstring(buffer,
219+ PAM_MSG_MEMBER(msg, i, msg))) != 0)
220+ fatal("%s: buffer error: %s",
221diff --git a/debian/patches/auth-pam-Immediately-report-interactive-instructions-to-c.patch b/debian/patches/auth-pam-Immediately-report-interactive-instructions-to-c.patch
222new file mode 100644
223index 0000000..f8f00bf
224--- /dev/null
225+++ b/debian/patches/auth-pam-Immediately-report-interactive-instructions-to-c.patch
226@@ -0,0 +1,73 @@
227+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
228+Date: Tue, 17 Oct 2023 04:27:32 +0200
229+Subject: auth-pam: Immediately report interactive instructions to clients
230+
231+SSH keyboard-interactive authentication method supports instructions but
232+sshd didn't show them until an user prompt was requested.
233+
234+This is quite inconvenient for various PAM modules that need to notify
235+an user without requiring for their explicit input.
236+
237+So, properly implement RFC4256 making instructions to be shown to users
238+when they are requested from PAM.
239+
240+Closes: https://bugzilla.mindrot.org/show_bug.cgi?id=2876
241+
242+Origin: https://github.com/openssh/openssh-portable/pull/452
243+---
244+ auth-pam.c | 21 ++++++++++++---------
245+ 1 file changed, 12 insertions(+), 9 deletions(-)
246+
247+diff --git a/auth-pam.c b/auth-pam.c
248+index 7a72e72..b756f0e 100644
249+--- a/auth-pam.c
250++++ b/auth-pam.c
251+@@ -140,6 +140,7 @@ typedef int SshPamDone;
252+ #define SshPamError -1
253+ #define SshPamNone 0
254+ #define SshPamAuthenticated 1
255++#define SshPamAgain 2
256+
257+ struct pam_ctxt {
258+ sp_pthread_t pam_thread;
259+@@ -868,6 +869,8 @@ sshpam_query(void *ctx, char **name, char **info,
260+ **prompts = NULL;
261+ plen = 0;
262+ *echo_on = xmalloc(sizeof(u_int));
263++ ctxt->pam_done = SshPamNone;
264++
265+ while (ssh_msg_recv(ctxt->pam_psock, buffer) == 0) {
266+ if (++nmesg > PAM_MAX_NUM_MSG)
267+ fatal_f("too many query messages");
268+@@ -888,15 +891,13 @@ sshpam_query(void *ctx, char **name, char **info,
269+ return (0);
270+ case PAM_ERROR_MSG:
271+ case PAM_TEXT_INFO:
272+- /* accumulate messages */
273+- len = plen + mlen + 2;
274+- **prompts = xreallocarray(**prompts, 1, len);
275+- strlcpy(**prompts + plen, msg, len - plen);
276+- plen += mlen;
277+- strlcat(**prompts + plen, "\n", len - plen);
278+- plen++;
279+- free(msg);
280+- break;
281++ *num = 0;
282++ free(*info);
283++ *info = msg; /* Steal the message */
284++ msg = NULL;
285++ ctxt->pam_done = SshPamAgain;
286++ sshbuf_free(buffer);
287++ return (0);
288+ case PAM_ACCT_EXPIRED:
289+ case PAM_MAXTRIES:
290+ if (type == PAM_ACCT_EXPIRED)
291+@@ -1001,6 +1002,8 @@ sshpam_respond(void *ctx, u_int num, char **resp)
292+ return KbdintResultSuccess;
293+ case SshPamNone:
294+ break;
295++ case SshPamAgain:
296++ return KbdintResultAgain;
297+ default:
298+ return KbdintResultFailure;
299+ }
300diff --git a/debian/patches/series b/debian/patches/series
301index 42a873f..aba5430 100644
302--- a/debian/patches/series
303+++ b/debian/patches/series
304@@ -28,3 +28,8 @@ systemd-socket-activation.patch
305 broken-zero-call-used-regs.patch
306 socket-activation-documentation.patch
307 test-set-UsePAM-no-on-some-tests.patch
308+auth-Add-KbdintResult-definition-to-define-result-values-.patch
309+auth-pam-Add-an-enum-to-define-the-PAM-done-status.patch
310+auth-pam-Add-debugging-information-when-we-receive-PAM-me.patch
311+auth-pam-Immediately-report-interactive-instructions-to-c.patch
312+sshconnect2-Write-kbd-interactive-service-info-and-instru.patch
313diff --git a/debian/patches/sshconnect2-Write-kbd-interactive-service-info-and-instru.patch b/debian/patches/sshconnect2-Write-kbd-interactive-service-info-and-instru.patch
314new file mode 100644
315index 0000000..238b98a
316--- /dev/null
317+++ b/debian/patches/sshconnect2-Write-kbd-interactive-service-info-and-instru.patch
318@@ -0,0 +1,108 @@
319+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
320+Date: Tue, 17 Oct 2023 06:12:03 +0200
321+Subject: sshconnect2: Write kbd-interactive service,
322+ info and instructions as utf-8
323+MIME-Version: 1.0
324+Content-Type: text/plain; charset="utf-8"
325+Content-Transfer-Encoding: 8bit
326+
327+As per the previous server change now the keyboard-interactive service
328+and instruction values could be reported as soon as they are available
329+and so they're not prompts anymore and not parsed like them.
330+
331+While this was already supported by the SSH client, these messages were
332+not properly written as the escaped sequences they contained were not
333+correctly reported.
334+
335+So for example a message containing "\" was represented as "\\" and
336+similarly for all the other C escape sequences.
337+
338+This was leading to more problems when it come to utf-8 chars, as they
339+were only represented by their octal representation.
340+
341+This was easily testable by adding a line like the one below to the
342+sshd PAM service:
343+ auth requisite pam_echo.so Hello SSHD! Want some 🍕?
344+
345+Which was causing this to be written instead:
346+ Hello SSHD! Want some \360\237\215\225?
347+
348+To handle this, instead of simply using fmprintf, we're using the notifier
349+in a way can be exposed to users in the proper format and UI.
350+
351+Origin: https://github.com/openssh/openssh-portable/pull/452
352+---
353+ sshconnect2.c | 33 ++++++++++++++++++++++++---------
354+ 1 file changed, 24 insertions(+), 9 deletions(-)
355+
356+diff --git a/sshconnect2.c b/sshconnect2.c
357+index cb584ad..7b9959d 100644
358+--- a/sshconnect2.c
359++++ b/sshconnect2.c
360+@@ -1231,6 +1231,7 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, struct ssh *ssh)
361+ char *info = NULL, *lang = NULL, *password = NULL, *retype = NULL;
362+ char prompt[256];
363+ const char *host;
364++ size_t info_len;
365+ int r;
366+
367+ debug2("input_userauth_passwd_changereq");
368+@@ -1240,11 +1241,15 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, struct ssh *ssh)
369+ "no authentication context");
370+ host = options.host_key_alias ? options.host_key_alias : authctxt->host;
371+
372+- if ((r = sshpkt_get_cstring(ssh, &info, NULL)) != 0 ||
373++ if ((r = sshpkt_get_cstring(ssh, &info, &info_len)) != 0 ||
374+ (r = sshpkt_get_cstring(ssh, &lang, NULL)) != 0)
375+ goto out;
376+- if (strlen(info) > 0)
377+- logit("%s", info);
378++ if (info_len > 0) {
379++ struct notifier_ctx *notifier = NULL;
380++ debug_f("input_userauth_passwd_changereq info: %s", info);
381++ notifier = notify_start(0, "%s", info);
382++ notify_complete(notifier, NULL);
383++ }
384+ if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
385+ (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 ||
386+ (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 ||
387+@@ -2098,8 +2103,10 @@ input_userauth_info_req(int type, u_int32_t seq, struct ssh *ssh)
388+ Authctxt *authctxt = ssh->authctxt;
389+ char *name = NULL, *inst = NULL, *lang = NULL, *prompt = NULL;
390+ char *display_prompt = NULL, *response = NULL;
391++ struct notifier_ctx *notifier = NULL;
392+ u_char echo = 0;
393+ u_int num_prompts, i;
394++ size_t name_len, inst_len;
395+ int r;
396+
397+ debug2_f("entering");
398+@@ -2109,14 +2116,22 @@ input_userauth_info_req(int type, u_int32_t seq, struct ssh *ssh)
399+
400+ authctxt->info_req_seen = 1;
401+
402+- if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0 ||
403+- (r = sshpkt_get_cstring(ssh, &inst, NULL)) != 0 ||
404++ if ((r = sshpkt_get_cstring(ssh, &name, &name_len)) != 0 ||
405++ (r = sshpkt_get_cstring(ssh, &inst, &inst_len)) != 0 ||
406+ (r = sshpkt_get_cstring(ssh, &lang, NULL)) != 0)
407+ goto out;
408+- if (strlen(name) > 0)
409+- logit("%s", name);
410+- if (strlen(inst) > 0)
411+- logit("%s", inst);
412++ if (name_len > 0) {
413++ debug_f("kbd int name: %s", name);
414++ notifier = notify_start(0, "%s", name);
415++ notify_complete(notifier, NULL);
416++ notifier = NULL;
417++ }
418++ if (inst_len > 0) {
419++ debug_f("kbd int inst: %s", inst);
420++ notifier = notify_start(0, "%s", inst);
421++ notify_complete(notifier, NULL);
422++ notifier = NULL;
423++ }
424+
425+ if ((r = sshpkt_get_u32(ssh, &num_prompts)) != 0)
426+ goto out;

Subscribers

People subscribed via source and target branches