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
|
From e4a1668e31569c0fdcc334c98fbc68ff0cd71e9c Mon Sep 17 00:00:00 2001
From: Pavel Raiskup <praiskup@redhat.com>
Date: Thu, 12 May 2022 09:02:43 +0200
Subject: [PATCH] Implement 'allow-unprivileged-ports' for the client
The restricted rootless container environment (e.g. OpenShift) doesn't
allow us to call seteuid(), call setuid binaries, or bind to privileged
ports. Therefore we need to have some opt-out for the use of privileged
ports.
With the very same option, the signd-side can already accept
such connections (before the option was useful when the source port was
changed to a non-privileged one, e.g. by some proxy).
Proposed upstream: https://github.com/openSUSE/obs-sign/pull/36
Needed for: https://pagure.io/copr/copr/pull-request/2193
---
sign.c | 6 ++++++
sock.c | 67 ++++++++++++++++++++++++++++++++++++----------------------
2 files changed, 48 insertions(+), 25 deletions(-)
diff --git a/sign.c b/sign.c
index f86718b..72e69ca 100644
--- a/sign.c
+++ b/sign.c
@@ -38,6 +38,7 @@
char *host;
int port = MYPORT;
char *test_sign;
+int allow_unprivileged_ports = 0;
static char *user;
static char *algouser;
static int allowuser;
@@ -1309,6 +1310,11 @@ read_sign_conf(const char *conf)
exit(1);
}
}
+ if (!strcmp(buf, "allow-unprivileged-ports"))
+ {
+ if (!strcmp(bp, "true"))
+ allow_unprivileged_ports = 1;
+ }
if (uid && !allowuser && !strcmp(buf, "allowuser"))
{
if (pwd && !strcmp(pwd->pw_name, bp))
diff --git a/sock.c b/sock.c
index 3008375..8b35683 100644
--- a/sock.c
+++ b/sock.c
@@ -37,6 +37,45 @@ extern char *test_sign;
extern char *host;
extern int port;
extern uid_t uid;
+extern int allow_unprivileged_ports;
+
+/* Best effort bindresvport(). We still try, but we don't enforce binding to
+ * a privileged source port (works only if 'allow-unprivileged-ports' is 'true'
+ * both on the client and server side. */
+static void
+do_bindresvport(void)
+{
+ if (uid)
+ {
+ if (seteuid(0))
+ {
+ if (allow_unprivileged_ports)
+ /* go with an unprivileged src port */
+ return;
+ perror("seteuid (for bindresvport)");
+ exit(1);
+ }
+ }
+
+ while (bindresvport(sock, NULL) != 0)
+ {
+ if (errno != EADDRINUSE)
+ {
+ perror("bindresvport");
+ exit(1);
+ }
+ sleep(1);
+ }
+
+ if (uid)
+ {
+ if (seteuid(uid))
+ {
+ perror("seteuid");
+ exit(1);
+ }
+ }
+}
void
opensocket(void)
@@ -70,31 +109,9 @@ opensocket(void)
perror("socket");
exit(1);
}
- if (uid)
- {
- if (seteuid(0))
- {
- perror("seteuid");
- exit(1);
- }
- }
- while (bindresvport(sock, NULL) != 0)
- {
- if (errno != EADDRINUSE)
- {
- perror("bindresvport");
- exit(1);
- }
- sleep(1);
- }
- if (uid)
- {
- if (seteuid(uid))
- {
- perror("seteuid");
- exit(1);
- }
- }
+
+ do_bindresvport();
+
if (connect(sock, (struct sockaddr *)&svt, sizeof(svt)))
{
perror(host);
--
2.36.1
|