Skip to content

Commit 79f663e

Browse files
blampeExeteres
andauthored
Add ability to specify host key (#794)
Community contribution from #769. Fixes #755. Co-authored-by: Fedor Chubukov <[email protected]>
1 parent 21bf788 commit 79f663e

File tree

16 files changed

+282
-3
lines changed

16 files changed

+282
-3
lines changed

provider/cmd/pulumi-resource-command/schema.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@
8686
"type": "string",
8787
"description": "The address of the resource to connect to."
8888
},
89+
"hostKey": {
90+
"type": "string",
91+
"description": "The expected host key to verify the server's identity. If not provided, the host key will be ignored."
92+
},
8993
"password": {
9094
"type": "string",
9195
"description": "The password we should use for the connection.",
@@ -163,6 +167,10 @@
163167
"type": "string",
164168
"description": "The address of the bastion host to connect to."
165169
},
170+
"hostKey": {
171+
"type": "string",
172+
"description": "The expected host key to verify the server's identity. If not provided, the host key will be ignored."
173+
},
166174
"password": {
167175
"type": "string",
168176
"description": "The password we should use for the connection to the bastion host.",

provider/pkg/provider/remote/connection.go

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ type connectionBase struct {
5252
AgentSocketPath *string `pulumi:"agentSocketPath,optional"`
5353
DialErrorLimit *int `pulumi:"dialErrorLimit,optional"`
5454
PerDialTimeout *int `pulumi:"perDialTimeout,optional"`
55+
HostKey *string `pulumi:"hostKey,optional"`
5556
}
5657

5758
func (c *Connection) Annotate(a infer.Annotator) {
@@ -70,13 +71,28 @@ func (c *Connection) Annotate(a infer.Annotator) {
7071
a.SetDefault(&c.DialErrorLimit, dialErrorDefault)
7172
a.Describe(&c.PerDialTimeout, "Max number of seconds for each dial attempt. 0 implies no maximum. Default value is 15 seconds.")
7273
a.SetDefault(&c.PerDialTimeout, 15)
74+
a.Describe(&c.HostKey, "The expected host key to verify the server's identity. If not provided, the host key will be ignored.")
7375
}
7476

7577
func (con *connectionBase) SShConfig() (*ssh.ClientConfig, error) {
78+
var hostKeyCallback ssh.HostKeyCallback
79+
var hostKeyAlgorithms []string
80+
if con.HostKey != nil {
81+
publicKey, _, _, _, err := ssh.ParseAuthorizedKey([]byte(*con.HostKey))
82+
if err != nil {
83+
return nil, fmt.Errorf("failed to parse host key: %w", err)
84+
}
85+
hostKeyCallback = ssh.FixedHostKey(publicKey)
86+
hostKeyAlgorithms = []string{publicKey.Type()}
87+
} else {
88+
hostKeyCallback = ssh.InsecureIgnoreHostKey()
89+
}
90+
7691
config := &ssh.ClientConfig{
77-
User: *con.User,
78-
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
79-
Timeout: time.Second * time.Duration(*con.PerDialTimeout),
92+
User: *con.User,
93+
HostKeyCallback: hostKeyCallback,
94+
HostKeyAlgorithms: hostKeyAlgorithms,
95+
Timeout: time.Second * time.Duration(*con.PerDialTimeout),
8096
}
8197
if con.PrivateKey != nil {
8298
var signer ssh.Signer

provider/pkg/provider/remote/proxyConnection.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,5 @@ func (c *ProxyConnection) Annotate(a infer.Annotator) {
3535
a.SetDefault(&c.DialErrorLimit, dialErrorDefault)
3636
a.Describe(&c.PerDialTimeout, "Max number of seconds for each dial attempt. 0 implies no maximum. Default value is 15 seconds.")
3737
a.SetDefault(&c.PerDialTimeout, 15)
38+
a.Describe(&c.HostKey, "The expected host key to verify the server's identity. If not provided, the host key will be ignored.")
3839
}

sdk/dotnet/Remote/Inputs/ConnectionArgs.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ public sealed class ConnectionArgs : global::Pulumi.ResourceArgs
3333
[Input("host", required: true)]
3434
public Input<string> Host { get; set; } = null!;
3535

36+
/// <summary>
37+
/// The expected host key to verify the server's identity. If not provided, the host key will be ignored.
38+
/// </summary>
39+
[Input("hostKey")]
40+
public Input<string>? HostKey { get; set; }
41+
3642
[Input("password")]
3743
private Input<string>? _password;
3844

sdk/dotnet/Remote/Inputs/ProxyConnectionArgs.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ public sealed class ProxyConnectionArgs : global::Pulumi.ResourceArgs
3333
[Input("host", required: true)]
3434
public Input<string> Host { get; set; } = null!;
3535

36+
/// <summary>
37+
/// The expected host key to verify the server's identity. If not provided, the host key will be ignored.
38+
/// </summary>
39+
[Input("hostKey")]
40+
public Input<string>? HostKey { get; set; }
41+
3642
[Input("password")]
3743
private Input<string>? _password;
3844

sdk/dotnet/Remote/Outputs/Connection.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ public sealed class Connection
2929
/// </summary>
3030
public readonly string Host;
3131
/// <summary>
32+
/// The expected host key to verify the server's identity. If not provided, the host key will be ignored.
33+
/// </summary>
34+
public readonly string? HostKey;
35+
/// <summary>
3236
/// The password we should use for the connection.
3337
/// </summary>
3438
public readonly string? Password;
@@ -65,6 +69,8 @@ private Connection(
6569

6670
string host,
6771

72+
string? hostKey,
73+
6874
string? password,
6975

7076
int? perDialTimeout,
@@ -82,6 +88,7 @@ private Connection(
8288
AgentSocketPath = agentSocketPath;
8389
DialErrorLimit = dialErrorLimit;
8490
Host = host;
91+
HostKey = hostKey;
8592
Password = password;
8693
PerDialTimeout = perDialTimeout;
8794
Port = port;

sdk/dotnet/Remote/Outputs/ProxyConnection.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ public sealed class ProxyConnection
2929
/// </summary>
3030
public readonly string Host;
3131
/// <summary>
32+
/// The expected host key to verify the server's identity. If not provided, the host key will be ignored.
33+
/// </summary>
34+
public readonly string? HostKey;
35+
/// <summary>
3236
/// The password we should use for the connection to the bastion host.
3337
/// </summary>
3438
public readonly string? Password;
@@ -61,6 +65,8 @@ private ProxyConnection(
6165

6266
string host,
6367

68+
string? hostKey,
69+
6470
string? password,
6571

6672
int? perDialTimeout,
@@ -76,6 +82,7 @@ private ProxyConnection(
7682
AgentSocketPath = agentSocketPath;
7783
DialErrorLimit = dialErrorLimit;
7884
Host = host;
85+
HostKey = hostKey;
7986
Password = password;
8087
PerDialTimeout = perDialTimeout;
8188
Port = port;

sdk/go/command/remote/pulumiTypes.go

Lines changed: 28 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sdk/java/src/main/java/com/pulumi/command/remote/inputs/ConnectionArgs.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,21 @@ public Output<String> host() {
6969
return this.host;
7070
}
7171

72+
/**
73+
* The expected host key to verify the server&#39;s identity. If not provided, the host key will be ignored.
74+
*
75+
*/
76+
@Import(name="hostKey")
77+
private @Nullable Output<String> hostKey;
78+
79+
/**
80+
* @return The expected host key to verify the server&#39;s identity. If not provided, the host key will be ignored.
81+
*
82+
*/
83+
public Optional<Output<String>> hostKey() {
84+
return Optional.ofNullable(this.hostKey);
85+
}
86+
7287
/**
7388
* The password we should use for the connection.
7489
*
@@ -180,6 +195,7 @@ private ConnectionArgs(ConnectionArgs $) {
180195
this.agentSocketPath = $.agentSocketPath;
181196
this.dialErrorLimit = $.dialErrorLimit;
182197
this.host = $.host;
198+
this.hostKey = $.hostKey;
183199
this.password = $.password;
184200
this.perDialTimeout = $.perDialTimeout;
185201
this.port = $.port;
@@ -270,6 +286,27 @@ public Builder host(String host) {
270286
return host(Output.of(host));
271287
}
272288

289+
/**
290+
* @param hostKey The expected host key to verify the server&#39;s identity. If not provided, the host key will be ignored.
291+
*
292+
* @return builder
293+
*
294+
*/
295+
public Builder hostKey(@Nullable Output<String> hostKey) {
296+
$.hostKey = hostKey;
297+
return this;
298+
}
299+
300+
/**
301+
* @param hostKey The expected host key to verify the server&#39;s identity. If not provided, the host key will be ignored.
302+
*
303+
* @return builder
304+
*
305+
*/
306+
public Builder hostKey(String hostKey) {
307+
return hostKey(Output.of(hostKey));
308+
}
309+
273310
/**
274311
* @param password The password we should use for the connection.
275312
*

sdk/java/src/main/java/com/pulumi/command/remote/inputs/ProxyConnectionArgs.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,21 @@ public Output<String> host() {
6868
return this.host;
6969
}
7070

71+
/**
72+
* The expected host key to verify the server&#39;s identity. If not provided, the host key will be ignored.
73+
*
74+
*/
75+
@Import(name="hostKey")
76+
private @Nullable Output<String> hostKey;
77+
78+
/**
79+
* @return The expected host key to verify the server&#39;s identity. If not provided, the host key will be ignored.
80+
*
81+
*/
82+
public Optional<Output<String>> hostKey() {
83+
return Optional.ofNullable(this.hostKey);
84+
}
85+
7186
/**
7287
* The password we should use for the connection to the bastion host.
7388
*
@@ -164,6 +179,7 @@ private ProxyConnectionArgs(ProxyConnectionArgs $) {
164179
this.agentSocketPath = $.agentSocketPath;
165180
this.dialErrorLimit = $.dialErrorLimit;
166181
this.host = $.host;
182+
this.hostKey = $.hostKey;
167183
this.password = $.password;
168184
this.perDialTimeout = $.perDialTimeout;
169185
this.port = $.port;
@@ -253,6 +269,27 @@ public Builder host(String host) {
253269
return host(Output.of(host));
254270
}
255271

272+
/**
273+
* @param hostKey The expected host key to verify the server&#39;s identity. If not provided, the host key will be ignored.
274+
*
275+
* @return builder
276+
*
277+
*/
278+
public Builder hostKey(@Nullable Output<String> hostKey) {
279+
$.hostKey = hostKey;
280+
return this;
281+
}
282+
283+
/**
284+
* @param hostKey The expected host key to verify the server&#39;s identity. If not provided, the host key will be ignored.
285+
*
286+
* @return builder
287+
*
288+
*/
289+
public Builder hostKey(String hostKey) {
290+
return hostKey(Output.of(hostKey));
291+
}
292+
256293
/**
257294
* @param password The password we should use for the connection to the bastion host.
258295
*

0 commit comments

Comments
 (0)