Skip to content

Commit

Permalink
Merge branch 'trunk' into xlin-pysshnpd-patch
Browse files Browse the repository at this point in the history
  • Loading branch information
XavierChanth authored May 3, 2024
2 parents a88db7f + cd8aecb commit bba55be
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,5 @@ class DefaultSshnpdArgs {
static const SupportedSshClient sshClient = SupportedSshClient.openssh;
static const int localSshdPort = 22;
static const String deviceGroupName = '__none__';
static const String sshPublicKeyPermissions = "";
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ const String sshnpDeviceNameRegex = r'[a-z0-9_]{1,36}';
const String invalidDeviceNameMsg = 'Device name must be alphanumeric'
' snake case, max length 36';
const String deviceNameFormatHelp = 'Alphanumeric snake case, max length 36.';
const String invalidSshKeyPermissionsMsg =
'Detected newline characters in the ssh public key permissions which malforms the authorized_keys file.';

bool invalidDeviceName(String test) {
return RegExp(sshnpDeviceNameRegex).allMatches(test).first.group(0) != test;
Expand Down
5 changes: 5 additions & 0 deletions packages/dart/noports_core/lib/src/sshnpd/sshnpd.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ abstract class Sshnpd {
/// Default set to [defaultLocalSshdPort]
abstract final int localSshdPort;

/// Permissions which are added to the authorized_keys file when adding
/// a public key via --sshpublickey being enabled.
/// e.g. PermitOpen="host-1:3389",PermitOpen="localhost:80"
abstract final String sshPublicKeyPermissions;

/// Permissions which are added to the authorized_keys file when adding
/// a newly-generated ephemeral public key.
/// e.g. PermitOpen="host-1:3389",PermitOpen="localhost:80"
Expand Down
21 changes: 18 additions & 3 deletions packages/dart/noports_core/lib/src/sshnpd/sshnpd_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ class SshnpdImpl implements Sshnpd {
@override
final int localSshdPort;

@override
final String sshPublicKeyPermissions;
final String _sshPublicKeySeparator; // ' ' if there are permissions else ''

@override
final String ephemeralPermissions;

Expand Down Expand Up @@ -96,23 +100,30 @@ class SshnpdImpl implements Sshnpd {
this.makeDeviceInfoVisible = false,
this.addSshPublicKeys = false,
this.localSshdPort = DefaultSshnpdArgs.localSshdPort,
this.sshPublicKeyPermissions = DefaultSshnpdArgs.sshPublicKeyPermissions,
required this.ephemeralPermissions,
required this.sshAlgorithm,
required this.deviceGroup,
required this.version,
required this.permitOpen,
this.authChecker,
}) {
}) : _sshPublicKeySeparator = (sshPublicKeyPermissions.isEmpty ? "" : " ") {
if (invalidDeviceName(device)) {
throw ArgumentError(invalidDeviceNameMsg);
}
logger.hierarchicalLoggingEnabled = true;
logger.logger.level = Level.SHOUT;

if (authChecker == null && policyManagerAtsign != null) {
authChecker = _NPAAuthChecker(this);
}

if (addSshPublicKeys) {
logger.info(
"Starting sshnpd with addSshPublicKeys on, using permissions: "
"'$sshPublicKeyPermissions'",
);
}

pingResponse = {
'devicename': device,
'version': version,
Expand Down Expand Up @@ -169,6 +180,7 @@ class SshnpdImpl implements Sshnpd {
makeDeviceInfoVisible: p.makeDeviceInfoVisible,
addSshPublicKeys: p.addSshPublicKeys,
localSshdPort: p.localSshdPort,
sshPublicKeyPermissions: p.sshPublicKeyPermissions,
ephemeralPermissions: p.ephemeralPermissions,
sshAlgorithm: p.sshAlgorithm,
deviceGroup: p.deviceGroup,
Expand Down Expand Up @@ -398,7 +410,10 @@ class SshnpdImpl implements Sshnpd {
var authKeysContent = await authKeys.readAsString();

if (!authKeysContent.contains(sshPublicKey)) {
authKeys.writeAsStringSync('\n$sshPublicKey', mode: FileMode.append);
authKeys.writeAsStringSync(
'$sshPublicKeyPermissions$_sshPublicKeySeparator$sshPublicKey',
mode: FileMode.append,
);
}
} catch (e) {
logger.severe("Error writing to"
Expand Down
20 changes: 19 additions & 1 deletion packages/dart/noports_core/lib/src/sshnpd/sshnpd_params.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class SshnpdParams {
final SupportedSshClient sshClient;
final String rootDomain;
final int localSshdPort;
final String sshPublicKeyPermissions;
final String ephemeralPermissions;
final SupportedSshAlgorithm sshAlgorithm;
final String deviceGroup;
Expand All @@ -43,6 +44,7 @@ class SshnpdParams {
required this.sshClient,
required this.rootDomain,
required this.localSshdPort,
required this.sshPublicKeyPermissions,
required this.ephemeralPermissions,
required this.sshAlgorithm,
required this.deviceGroup,
Expand Down Expand Up @@ -91,6 +93,14 @@ class SshnpdParams {
if (r.wasParsed('hide')) {
makeDeviceInfoVisible = !r['hide'];
}
// Normalize/validate the sshPublicKeyPermissions
String normalizedPermissions = r['sshpublickey-permissions'].trim();
// don't remove newlines, since internal whitespace may be important to what they are trying to do
if (RegExp(r'[\r\n]').hasMatch(normalizedPermissions)) {
// bad input... newlines are dangerous
throw ArgumentError(invalidSshKeyPermissionsMsg);
}

return SshnpdParams(
device: r['device'],
username: getUserName(throwIfNull: true)!,
Expand All @@ -107,6 +117,7 @@ class SshnpdParams {
rootDomain: r['root-domain'],
localSshdPort:
int.tryParse(r['local-sshd-port']) ?? DefaultSshnpdArgs.localSshdPort,
sshPublicKeyPermissions: normalizedPermissions,
ephemeralPermissions: r['ephemeral-permissions'],
sshAlgorithm: SupportedSshAlgorithm.fromString(r['ssh-algorithm']),
deviceGroup: r['device-group'],
Expand Down Expand Up @@ -237,7 +248,14 @@ class SshnpdParams {
defaultsTo: DefaultSshnpdArgs.localSshdPort.toString(),
mandatory: false,
);

parser.addOption(
'sshpublickey-permissions',
abbr: 'S',
defaultsTo: DefaultSshnpdArgs.sshPublicKeyPermissions,
help:
'When --sshpublickey is enabled, will include the specified permissions'
' in the public key entry in authorized_keys',
);
parser.addOption('ephemeral-permissions',
help: 'The permissions which will be added to the authorized_keys file'
' for the ephemeral public keys which are generated when a client'
Expand Down
5 changes: 5 additions & 0 deletions packages/dart/sshnoports/bin/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Ignore everything (generated development binaries)
*
# Allow dart files
!*.dart
!.gitignore

0 comments on commit bba55be

Please sign in to comment.