Skip to content

Commit

Permalink
Add method to allow elevated privelege operations from Posix
Browse files Browse the repository at this point in the history
  • Loading branch information
hedgecrw committed Jan 28, 2022
1 parent 28c21ec commit bc2ec3e
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 2 deletions.
12 changes: 10 additions & 2 deletions src/main/c/Posix/PosixHelperFunctions.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* PosixHelperFunctions.c
*
* Created on: Mar 10, 2015
* Last Updated on: Jan 25, 2022
* Last Updated on: Jan 28, 2022
* Author: Will Hedgecock
*
* Copyright (C) 2012-2022 Fazecast, Inc.
Expand Down Expand Up @@ -1652,17 +1652,25 @@ int verifyAndSetUserPortGroup(const char *portFile)
}

// Attempt to add the user to the group that owns the port
char *addUserToGroupCmd = (char*)malloc(256);
if (!userPartOfPortGroup)
{
struct group *portGroup;
struct passwd *userDetails;
if ((portGroup = getgrgid(fileStats.st_gid)) && (userDetails = getpwuid(geteuid())))
{
char *addUserToGroupCmd = (char*)malloc(256);
snprintf(addUserToGroupCmd, 256, "sudo usermod -a -G %s %s", portGroup->gr_name, userDetails->pw_name);
userCanAccess = (system(addUserToGroupCmd) == 0);
}
}

// Attempt to enable all read/write port permissions
snprintf(addUserToGroupCmd, 256, "sudo chmod 666 %s", portFile);
userCanAccess = (system(addUserToGroupCmd) == 0) || userCanAccess;

// Clean up memory
free(addUserToGroupCmd);
free(userGroups);
}

// Return whether the user can currently access the serial port
Expand Down
9 changes: 9 additions & 0 deletions src/main/c/Posix/SerialPort_Posix.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ jfieldID flowControlField;
jfieldID sendDeviceQueueSizeField;
jfieldID receiveDeviceQueueSizeField;
jfieldID disableExclusiveLockField;
jfieldID requestElevatedPermissionsField;
jfieldID rs485ModeField;
jfieldID rs485ActiveHighField;
jfieldID rs485EnableTerminationField;
Expand Down Expand Up @@ -312,6 +313,8 @@ JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_initializeLibrar
if (checkJniError(env, __LINE__ - 1)) return;
disableExclusiveLockField = (*env)->GetFieldID(env, serialCommClass, "disableExclusiveLock", "Z");
if (checkJniError(env, __LINE__ - 1)) return;
requestElevatedPermissionsField = (*env)->GetFieldID(env, serialCommClass, "requestElevatedPermissions", "Z");
if (checkJniError(env, __LINE__ - 1)) return;
rs485ModeField = (*env)->GetFieldID(env, serialCommClass, "rs485Mode", "Z");
if (checkJniError(env, __LINE__ - 1)) return;
rs485ActiveHighField = (*env)->GetFieldID(env, serialCommClass, "rs485ActiveHigh", "Z");
Expand Down Expand Up @@ -406,6 +409,8 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative(
if (checkJniError(env, __LINE__ - 1)) return 0;
unsigned char disableExclusiveLock = (*env)->GetBooleanField(env, obj, disableExclusiveLockField);
if (checkJniError(env, __LINE__ - 1)) return 0;
unsigned char requestElevatedPermissions = (*env)->GetBooleanField(env, obj, requestElevatedPermissionsField);
if (checkJniError(env, __LINE__ - 1)) return 0;
unsigned char disableAutoConfig = (*env)->GetBooleanField(env, obj, disableConfigField);
if (checkJniError(env, __LINE__ - 1)) return 0;
unsigned char autoFlushIOBuffers = (*env)->GetBooleanField(env, obj, autoFlushIOBuffersField);
Expand All @@ -427,6 +432,10 @@ JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative(
return 0;
}

// Fix user permissions so that they can open the port, if allowed
if (requestElevatedPermissions)
verifyAndSetUserPortGroup(portName);

// Try to open the serial port with read/write access
port->errorLineNumber = lastErrorLineNumber = __LINE__ + 1;
if ((port->handle = open(portName, O_RDWR | O_NOCTTY | O_NONBLOCK | O_CLOEXEC)) > 0)
Expand Down

0 comments on commit bc2ec3e

Please sign in to comment.