diff --git a/src/add-ons/network_settings/sshd/Jamfile b/src/add-ons/network_settings/sshd/Jamfile index f43cc095c2..4e4c1c0840 100644 --- a/src/add-ons/network_settings/sshd/Jamfile +++ b/src/add-ons/network_settings/sshd/Jamfile @@ -1,7 +1,7 @@ SubDir HAIKU_TOP src add-ons network_settings sshd ; UsePublicHeaders [ FDirName add-ons network_settings ] ; -UsePrivateHeaders shared ; +UsePrivateHeaders app libroot kernel net shared ; Addon SSHService : SSHServiceAddOn.cpp diff --git a/src/add-ons/network_settings/sshd/SSHServiceAddOn.cpp b/src/add-ons/network_settings/sshd/SSHServiceAddOn.cpp index f2efaaf785..3b7030424e 100644 --- a/src/add-ons/network_settings/sshd/SSHServiceAddOn.cpp +++ b/src/add-ons/network_settings/sshd/SSHServiceAddOn.cpp @@ -4,17 +4,26 @@ * * Authors: * Axel Dörfler, + * Ingo Weinhold */ +#include + #include #include #include +#include #include #include #include #include +#include +#include +#include +#include + using namespace BNetworkKit; @@ -50,9 +59,11 @@ private: bool _IsEnabled() const; void _Enable(); void _Disable(); + void _UpdateEnableButton(); private: BNetworkSettings& fSettings; + BButton* fEnableButton; }; @@ -99,7 +110,7 @@ ServiceView::ServiceView(BNetworkSettings& settings) descriptionView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); descriptionView->MakeEditable(false); - BButton* button = new BButton("toggler", B_TRANSLATE("Enable"), + fEnableButton = new BButton("toggler", B_TRANSLATE("Enable"), new BMessage(kMsgToggleService)); BLayoutBuilder::Group<>(this, B_VERTICAL) @@ -107,9 +118,10 @@ ServiceView::ServiceView(BNetworkSettings& settings) .Add(descriptionView) .AddGroup(B_HORIZONTAL) .AddGlue() - .Add(button); + .Add(fEnableButton); SetExplicitMinSize(BSize(200, B_SIZE_UNSET)); + _UpdateEnableButton(); } @@ -121,6 +133,7 @@ ServiceView::~ServiceView() void ServiceView::ConfigurationUpdated(const BMessage& message) { + _UpdateEnableButton(); } @@ -133,6 +146,8 @@ ServiceView::MessageReceived(BMessage* message) _Disable(); else _Enable(); + + _UpdateEnableButton(); break; default: BView::MessageReceived(message); @@ -144,14 +159,72 @@ ServiceView::MessageReceived(BMessage* message) bool ServiceView::_IsEnabled() const { - BNetworkServiceSettings settings = fSettings.Service("ssh"); - return settings.IsEnabled(); + BMessage request(kMsgIsServiceRunning); + request.AddString("name", "ssh"); + + BMessenger networkServer(kNetServerSignature); + BMessage reply; + status_t status = networkServer.SendMessage(&request, &reply); + if (status == B_OK) + return reply.GetBool("running"); + + return false; } void ServiceView::_Enable() { + if (getpwnam("sshd") == NULL) { + // We need to create a dedicated user for the service + // The following code is copied from useradd, and should be moved + // to a public class. + gid_t groupID = 100; + + // Find an unused user ID + uid_t userID = 1000; + while (getpwuid(userID) != NULL) + userID++; + + const char* home = "/boot/home"; + int expiration = 99999; + int inactive = -1; + const char* shell = "/bin/sh"; + const char* realName = ""; + + int min = -1; + int max = -1; + int warn = 7; + + // prepare request for the registrar + KMessage message(BPrivate::B_REG_UPDATE_USER); + if (message.AddInt32("uid", userID) == B_OK + && message.AddInt32("gid", groupID) == B_OK + && message.AddString("name", "sshd") == B_OK + && message.AddString("password", "x") == B_OK + && message.AddString("home", home) == B_OK + && message.AddString("shell", shell) == B_OK + && message.AddString("real name", realName) == B_OK + && message.AddString("shadow password", "!") == B_OK + && message.AddInt32("last changed", time(NULL)) == B_OK + && message.AddInt32("min", min) == B_OK + && message.AddInt32("max", max) == B_OK + && message.AddInt32("warn", warn) == B_OK + && message.AddInt32("inactive", inactive) == B_OK + && message.AddInt32("expiration", expiration) == B_OK + && message.AddInt32("flags", 0) == B_OK + && message.AddBool("add user", true) == B_OK) { + // send the request + KMessage reply; + status_t error = send_authentication_request_to_registrar(message, + reply); + if (error != B_OK) { + fprintf(stderr, "Error: Failed to create user: %s\n", + strerror(error)); + } + } + } + BNetworkServiceSettings settings; settings.SetName("ssh"); settings.SetStandAlone(true); @@ -168,10 +241,19 @@ ServiceView::_Enable() void ServiceView::_Disable() { + // Since the sshd user may have been customized, we don't remove it fSettings.RemoveService("ssh"); } +void +ServiceView::_UpdateEnableButton() +{ + fEnableButton->SetLabel(_IsEnabled() + ? B_TRANSLATE("Disable") : B_TRANSLATE("Enable")); +} + + // #pragma mark -