Skip to content

Commit cbdfee7

Browse files
authored
Merge pull request #156 from sleeyax/feat/external-proxy
2 parents 5f0a9d7 + 563d85a commit cbdfee7

File tree

9 files changed

+118
-53
lines changed

9 files changed

+118
-53
lines changed

src-go/server/go.mod

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
module server
22

3-
go 1.22.0
3+
go 1.24.1
44

55
toolchain go1.25.6
66

77
require (
8-
github.com/bogdanfinn/fhttp v0.5.36
9-
github.com/bogdanfinn/tls-client v1.8.0
10-
github.com/bogdanfinn/utls v1.6.5
8+
github.com/bogdanfinn/fhttp v0.6.6
9+
github.com/bogdanfinn/tls-client v1.13.1
10+
github.com/bogdanfinn/utls v1.7.7-barnius
1111
)
1212

1313
require (
14-
github.com/andybalholm/brotli v1.1.1 // indirect
15-
github.com/cloudflare/circl v1.5.0 // indirect
16-
github.com/klauspost/compress v1.17.11 // indirect
17-
github.com/quic-go/quic-go v0.48.1 // indirect
14+
github.com/andybalholm/brotli v1.2.0 // indirect
15+
github.com/bdandy/go-errors v1.2.2 // indirect
16+
github.com/bdandy/go-socks4 v1.2.3 // indirect
17+
github.com/bogdanfinn/quic-go-utls v1.0.7-utls // indirect
18+
github.com/klauspost/compress v1.18.2 // indirect
19+
github.com/quic-go/qpack v0.6.0 // indirect
1820
github.com/tam7t/hpkp v0.0.0-20160821193359-2b70b4024ed5 // indirect
19-
golang.org/x/crypto v0.29.0 // indirect
20-
golang.org/x/net v0.31.0 // indirect
21-
golang.org/x/sys v0.27.0 // indirect
22-
golang.org/x/text v0.20.0 // indirect
21+
golang.org/x/crypto v0.46.0 // indirect
22+
golang.org/x/net v0.48.0 // indirect
23+
golang.org/x/sys v0.39.0 // indirect
24+
golang.org/x/text v0.32.0 // indirect
2325
)
24-
25-
replace github.com/ooni/oohttp => github.com/sleeyax/oohttp v0.0.0-20230603105812-6ac0447b1a8e

src-go/server/go.sum

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,46 @@
1-
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
2-
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
3-
github.com/bogdanfinn/fhttp v0.5.34 h1:avRD2JNYqj6I6DqjSrI9tl8mP8Nk7T4CCmUsPz7afhg=
4-
github.com/bogdanfinn/fhttp v0.5.34/go.mod h1:BlcawVfXJ4uhk5yyNGOOY2bwo8UmMi6ccMszP1KGLkU=
5-
github.com/bogdanfinn/fhttp v0.5.36 h1:t1sO/EkO4K40QD/Ti8f6t80leZIdh2AaeLfN7dMvjH8=
6-
github.com/bogdanfinn/fhttp v0.5.36/go.mod h1:BlcawVfXJ4uhk5yyNGOOY2bwo8UmMi6ccMszP1KGLkU=
7-
github.com/bogdanfinn/tls-client v1.8.0 h1:IB44SqKa0XKdx3GYXpRbkqN3+tsBtg9RJYRsl36boOA=
8-
github.com/bogdanfinn/tls-client v1.8.0/go.mod h1:ehNITC7JBFeh6S7QNWtfD+PBKm0RsqvizAyyij2d/6g=
9-
github.com/bogdanfinn/utls v1.6.5 h1:rVMQvhyN3zodLxKFWMRLt19INGBCZ/OM2/vBWPNIt1w=
10-
github.com/bogdanfinn/utls v1.6.5/go.mod h1:czcHxHGsc1q9NjgWSeSinQZzn6MR76zUmGVIGanSXO0=
11-
github.com/cloudflare/circl v1.5.0 h1:hxIWksrX6XN5a1L2TI/h53AGPhNHoUBo+TD1ms9+pys=
12-
github.com/cloudflare/circl v1.5.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
1+
github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ=
2+
github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
3+
github.com/bdandy/go-errors v1.2.2 h1:WdFv/oukjTJCLa79UfkGmwX7ZxONAihKu4V0mLIs11Q=
4+
github.com/bdandy/go-errors v1.2.2/go.mod h1:NkYHl4Fey9oRRdbB1CoC6e84tuqQHiqrOcZpqFEkBxM=
5+
github.com/bdandy/go-socks4 v1.2.3 h1:Q6Y2heY1GRjCtHbmlKfnwrKVU/k81LS8mRGLRlmDlic=
6+
github.com/bdandy/go-socks4 v1.2.3/go.mod h1:98kiVFgpdogR8aIGLWLvjDVZ8XcKPsSI/ypGrO+bqHI=
7+
github.com/bogdanfinn/fhttp v0.6.6 h1:S0+4w0wPCiUg0NId6dGIJnR2uNV5/eFYIolCYErGruo=
8+
github.com/bogdanfinn/fhttp v0.6.6/go.mod h1:A+EKDzMx2hb4IUbMx4TlkoHnaJEiLl8r/1Ss1Y+5e5M=
9+
github.com/bogdanfinn/quic-go-utls v1.0.7-utls h1:opxU/wt2C6FcD3rkGSOwfpQgfGSFx9eAKYQrFwYBzuo=
10+
github.com/bogdanfinn/quic-go-utls v1.0.7-utls/go.mod h1:bk8QMY2KypO8A6LzHJ7C4+bdB0ksLOd6NZt600wXYe8=
11+
github.com/bogdanfinn/tls-client v1.13.1 h1:O2sfv8JK8R7nNz+Km675VOIajum4sMqOb/ys/4gXfPQ=
12+
github.com/bogdanfinn/tls-client v1.13.1/go.mod h1:4ZnckBKYWaQD9wq55cpUr5/2i45cCBAG+2V3fge+yvQ=
13+
github.com/bogdanfinn/utls v1.7.7-barnius h1:OuJ497cc7F3yKNVHRsYPQdGggmk5x6+V5ZlrCR7fOLU=
14+
github.com/bogdanfinn/utls v1.7.7-barnius/go.mod h1:aAK1VZQlpKZClF1WEQeq6kyclbkPq4hz6xTbB5xSlmg=
1315
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
1416
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
15-
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
16-
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
17+
github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk=
18+
github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
1719
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
1820
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
19-
github.com/quic-go/quic-go v0.48.1 h1:y/8xmfWI9qmGTc+lBr4jKRUWLGSlSigv847ULJ4hYXA=
20-
github.com/quic-go/quic-go v0.48.1/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs=
21-
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
22-
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
21+
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
22+
github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=
23+
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
24+
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
2325
github.com/tam7t/hpkp v0.0.0-20160821193359-2b70b4024ed5 h1:YqAladjX7xpA6BM04leXMWAEjS0mTZ5kUU9KRBriQJc=
2426
github.com/tam7t/hpkp v0.0.0-20160821193359-2b70b4024ed5/go.mod h1:2JjD2zLQYH5HO74y5+aE3remJQvl6q4Sn6aWA2wD1Ng=
2527
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
2628
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
27-
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
28-
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
29-
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
30-
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
31-
golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
32-
golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
33-
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
34-
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
35-
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
36-
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
29+
go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko=
30+
go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o=
31+
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
32+
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
33+
golang.org/x/net v0.0.0-20211104170005-ce137452f963/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
34+
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
35+
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
36+
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
37+
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
38+
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
39+
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
40+
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
41+
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
42+
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
43+
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
44+
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
3745
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
3846
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

src-go/server/server.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ package server
33
import (
44
"context"
55
"fmt"
6-
fhttp "github.com/bogdanfinn/fhttp"
7-
utls "github.com/bogdanfinn/utls"
86
"io"
97
"net"
8+
9+
fhttp "github.com/bogdanfinn/fhttp"
10+
utls "github.com/bogdanfinn/utls"
1011
)
1112

1213
// ConfigurationHeaderKey is the name of the header field that contains the RoundTripper configuration.

src-go/server/transport.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ import (
44
"encoding/json"
55
"errors"
66
"fmt"
7+
"strings"
8+
79
tls_client "github.com/bogdanfinn/tls-client"
810
"github.com/bogdanfinn/tls-client/profiles"
911
utls "github.com/bogdanfinn/utls"
10-
"strings"
1112
)
1213

1314
type TransportConfig struct {
@@ -38,6 +39,9 @@ type TransportConfig struct {
3839

3940
// HeaderOrder is the order of headers to be sent in the request.
4041
HeaderOrder []string
42+
43+
// ExternalProxyUrl is an optional upstream proxy (format: `http://user:pass@host:port`).
44+
ExternalProxyUrl string
4145
}
4246

4347
func ParseTransportConfig(data string) (*TransportConfig, error) {
@@ -64,6 +68,10 @@ func NewClient(config *TransportConfig) (tls_client.HttpClient, error) {
6468
options = append(options, tls_client.WithTimeoutSeconds(config.HttpTimeout))
6569
}
6670

71+
if config.ExternalProxyUrl != "" {
72+
options = append(options, tls_client.WithProxyUrl(config.ExternalProxyUrl))
73+
}
74+
6775
// The order of precedence is:
6876
// 1. Custom client hello from intercept proxy
6977
// 2. Custom client hello from hex string
@@ -91,6 +99,8 @@ func NewClient(config *TransportConfig) (tls_client.HttpClient, error) {
9199
defaultProfile.GetConnectionFlow(),
92100
defaultProfile.GetPriorities(),
93101
defaultProfile.GetHeaderPriority(),
102+
defaultProfile.GetStreamID(),
103+
defaultProfile.GetAllowHTTP(),
94104
)
95105

96106
options = append(options, tls_client.WithClientProfile(customClientProfile))

src/main/java/burp/Extension.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import burp.api.montoya.proxy.http.ProxyRequestToBeSentAction;
1010
import com.google.gson.Gson;
1111

12+
import java.net.URI;
1213
import java.net.URL;
1314
import java.nio.charset.StandardCharsets;
1415
import java.util.Objects;
@@ -60,7 +61,7 @@ public ProxyRequestReceivedAction handleRequestReceived(InterceptedRequest inter
6061

6162
private ProxyRequestToBeSentAction processHttpRequest(InterceptedRequest request) {
6263
try {
63-
var requestURL = new URL(request.url());
64+
var requestURL = new URI(request.url()).toURL();
6465

6566
if (requestURL.getHost().equals("awesome-tls-error")) {
6667
throw new Error(new String(request.body().getBytes(), StandardCharsets.UTF_8));
@@ -77,7 +78,7 @@ private ProxyRequestToBeSentAction processHttpRequest(InterceptedRequest request
7778
transportConfig.HeaderOrder = headerOrder;
7879

7980
var goConfigJSON = gson.toJson(transportConfig);
80-
var url = new URL("https://" + settings.getSpoofProxyAddress());
81+
var url = new URI("https://" + settings.getSpoofProxyAddress()).toURL();
8182
var httpService = HttpService.httpService(url.getHost(), url.getPort(), Objects.equals(url.getProtocol(), "https"));
8283
var nextRequest = request.withService(httpService).withAddedHeader(HEADER_KEY, goConfigJSON);
8384

src/main/java/burp/Settings.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@ public class Settings {
1313
private final String hexClientHello = "HexClientHello";
1414
private final String useInterceptedFingerprint = "UseInterceptedFingerprint";
1515
private final String httpTimeout = "HttpTimeout";
16+
private final String externalProxyUrl = "ExternalProxyUrl";
1617

1718
public static final String DEFAULT_SPOOF_PROXY_ADDRESS = "127.0.0.1:8887";
1819
public static final String DEFAULT_INTERCEPT_PROXY_ADDRESS = "127.0.0.1:8886";
1920
public static final String DEFAULT_BURP_PROXY_ADDRESS = "127.0.0.1:8080";
2021
public static final Integer DEFAULT_HTTP_TIMEOUT = 30;
2122
public static final String DEFAULT_TLS_FINGERPRINT = "default";
2223
public static final Boolean USE_INTERCEPTED_FINGERPRINT = false;
24+
public static final String DEFAULT_EXTERNAL_PROXY_URL = "";
2325

2426
public Settings(MontoyaApi api) {
2527
this.storage = api.persistence().preferences();
@@ -120,6 +122,14 @@ public void setHexClientHello(String hexClientHello) {
120122
this.write(this.hexClientHello, hexClientHello);
121123
}
122124

125+
public String getExternalProxyUrl() {
126+
return this.read(this.externalProxyUrl, DEFAULT_EXTERNAL_PROXY_URL);
127+
}
128+
129+
public void setExternalProxyUrl(String externalProxyUrl) {
130+
this.write(this.externalProxyUrl, externalProxyUrl);
131+
}
132+
123133
public String[] getFingerprints() {
124134
return ServerLibrary.INSTANCE.GetFingerprints().split("\n");
125135
}
@@ -132,6 +142,7 @@ public TransportConfig toTransportConfig() {
132142
transportConfig.UseInterceptedFingerprint = this.getUseInterceptedFingerprint();
133143
transportConfig.BurpAddr = this.getBurpProxyAddress();
134144
transportConfig.InterceptProxyAddr = this.getInterceptProxyAddress();
145+
transportConfig.ExternalProxyUrl = this.getExternalProxyUrl();
135146
return transportConfig;
136147
}
137148
}

src/main/java/burp/SettingsTab.form

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<properties/>
1818
<border type="none"/>
1919
<children>
20-
<grid id="65d0" binding="panelSettings" layout-manager="GridLayoutManager" row-count="10" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
20+
<grid id="65d0" binding="panelSettings" layout-manager="GridLayoutManager" row-count="12" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
2121
<margin top="0" left="0" bottom="0" right="0"/>
2222
<constraints>
2323
<tabbedpane title="settings"/>
@@ -79,10 +79,29 @@
7979
<toolTipText value="The maximum amount of time a dial will wait for a connect to complete."/>
8080
</properties>
8181
</component>
82+
<component id="e1a2b" class="javax.swing.JLabel" binding="labelExternalProxyUrl">
83+
<constraints>
84+
<grid row="8" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
85+
</constraints>
86+
<properties>
87+
<text value="External proxy URL:"/>
88+
<toolTipText value=""/>
89+
</properties>
90+
</component>
91+
<component id="f3c4d" class="javax.swing.JTextField" binding="textFieldExternalProxyUrl">
92+
<constraints>
93+
<grid row="9" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
94+
<preferred-size width="150" height="-1"/>
95+
</grid>
96+
</constraints>
97+
<properties>
98+
<toolTipText value="Upstream proxy (e.g. socks5://127.0.0.1:1080 or http://127.0.0.1:8080)"/>
99+
</properties>
100+
</component>
82101
<grid id="4bfb5" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
83102
<margin top="0" left="0" bottom="0" right="0"/>
84103
<constraints>
85-
<grid row="9" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
104+
<grid row="11" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
86105
</constraints>
87106
<properties/>
88107
<border type="none"/>
@@ -111,7 +130,7 @@
111130
</component>
112131
<component id="da183" class="javax.swing.JButton" binding="buttonSave">
113132
<constraints>
114-
<grid row="8" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
133+
<grid row="10" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
115134
</constraints>
116135
<properties>
117136
<text value="Save all settings"/>

0 commit comments

Comments
 (0)