-
Notifications
You must be signed in to change notification settings - Fork 5
RDKEMW-10284: Migrate stunnel to use P12 cert #364
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
Reason for change: To integrate SE based device cert for mTls connectivity in stunnel Test Procedure: Build and verify SHORTS connectivity Risks: None Priority: P1 Signed-off-by: ldonth501 <LasyaPrakarsha_DonthiVenkata@comcast.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR refactors the startStunnel.sh script to improve stunnel configuration management, add retry logic for PID file availability, and implement secure file descriptor handling for passcode management.
Key Changes
- Moved environment variable exports (
TERMandHOME) to after sourcing configuration files - Enhanced device type detection with case-insensitive checking and additional logging
- Implemented dynamic file descriptor allocation with named pipe for secure passcode handling
- Added retry logic for stunnel PID file reading with improved error handling
- Changed certificate path variable from
CERT_FILEtoCERT_PATH
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Get the next available file descriptor and export if its valid | ||
| FD_NUMBER=$(get_next_fd) | ||
| if [ $? -eq 0 ]; then | ||
| export FD_NUMBER | ||
|
|
||
| # Create a named pipe | ||
| PIPE=$(mktemp -u) | ||
| mkfifo "$PIPE" | ||
|
|
||
| # Open the pipe using the available FD | ||
| eval "exec $FD_NUMBER<>$PIPE" | ||
|
|
||
| #removing the pipe after opening | ||
| rm "$PIPE" | ||
|
|
||
| #Writing passcode to open file descriptor | ||
| echo "$(eval "$PASSCODE")" >&$FD_NUMBER & | ||
| else | ||
| echo "Error: No available file descriptor to use." >&2 | ||
| fi |
Copilot
AI
Nov 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing documentation: The purpose of creating and exporting the FD_NUMBER file descriptor with the PASSCODE is not clear. Add comments explaining:
- Why this file descriptor needs to be exported
- Which process/command will consume it
- How it's used for authentication or other purposes
This would improve maintainability and help future developers understand this security-sensitive code.
| #removing the pipe after opening | ||
| rm "$PIPE" | ||
|
|
||
| #Writing passcode to open file descriptor |
Copilot
AI
Nov 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Inconsistent comment style: This comment uses lowercase and no punctuation at the end. Consider maintaining consistent comment style:
# Writing passcode to open file descriptor| #Writing passcode to open file descriptor | |
| # Writing passcode to open file descriptor. |
| rm -f $STUNNEL_PID_FILE | ||
| rm -f $CA_FILE | ||
| if [ "x$CRED_INDEX" == "x0" ]; then | ||
| touch /tmp/.$SE_DEVICE_CERT |
Copilot
AI
Nov 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable SE_DEVICE_CERT is used without being defined in this script. Ensure this variable is properly defined in one of the sourced files, or add a validation check before use to prevent path errors:
if [ -z "$SE_DEVICE_CERT" ]; then
echo_t "STUNNEL: ERROR - SE_DEVICE_CERT is not defined"
else
touch /tmp/.$SE_DEVICE_CERT
fi| rm "$PIPE" | ||
|
|
||
| #Writing passcode to open file descriptor | ||
| echo "$(eval "$PASSCODE")" >&$FD_NUMBER & |
Copilot
AI
Nov 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Race condition: The file descriptor is written to in a background process (&), but there's no synchronization to ensure the data is written before it's potentially read elsewhere. If the code using FD_NUMBER reads from it immediately, it might read before the data is written. Consider removing the & to write synchronously, or implement proper synchronization if async is required.
| echo "$(eval "$PASSCODE")" >&$FD_NUMBER & | |
| echo "$(eval "$PASSCODE")" >&$FD_NUMBER |
| rm "$PIPE" | ||
|
|
||
| #Writing passcode to open file descriptor | ||
| echo "$(eval "$PASSCODE")" >&$FD_NUMBER & |
Copilot
AI
Nov 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential resource leak: If get_next_fd() fails (returns 1), the script continues execution without a valid file descriptor. The opened file descriptor and pipe are never cleaned up explicitly. Consider adding cleanup logic in an exit trap or failure path to ensure resources are properly released.
| echo "$(eval "$PASSCODE")" >&$FD_NUMBER & | |
| echo "$(eval "$PASSCODE")" >&$FD_NUMBER & | |
| # Trap to cleanup the file descriptor on exit | |
| trap 'if [ -n "$FD_NUMBER" ]; then eval "exec $FD_NUMBER>&-"; fi' EXIT |
|
|
||
| isShortsenabled=`tr181 Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.SHORTS.Enable 2>&1 > /dev/null` | ||
| echo_t "isShortsenabled = $isShortsenabled " | ||
| if [ $isShortsenabled == "false" ];then |
Copilot
AI
Nov 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unsafe comparison: The variable isShortsenabled could be empty or unset, which would cause a syntax error. Use safer comparison with quotes:
if [ "$isShortsenabled" == "false" ];then| if [ $isShortsenabled == "false" ];then | |
| if [ "$isShortsenabled" == "false" ];then |
| if [ "$DEVICETYPE" == "TEST" ] || [ "$DEVICETYPE" == "test" ]; then | ||
| echo_t "STUNNEL: Device type is TEST" | ||
| t2CountNotify "SHORTS_DEVICE_TYPE_TEST" | ||
| echo "checkHost = $JUMP_FQDN" >> $STUNNEL_CONF_FILE | ||
| echo "checkHost = $DEV_SAN" >> $STUNNEL_CONF_FILE | ||
| else | ||
| echo_t "STUNNEL: Device type is PROD" | ||
| t2CountNotify "SHORTS_DEVICE_TYPE_PROD" | ||
| echo "checkHost = $JUMP_FQDN" >> $STUNNEL_CONF_FILE | ||
| echo "checkHost = $PROD_SAN" >> $STUNNEL_CONF_FILE | ||
| fi |
Copilot
AI
Nov 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overly broad PROD classification: The else branch treats any non-TEST value (including malformed or unexpected values) as PROD. Consider being more explicit:
if [ "$DEVICETYPE" == "TEST" ] || [ "$DEVICETYPE" == "test" ]; then
echo_t "STUNNEL: Device type is TEST"
t2CountNotify "SHORTS_DEVICE_TYPE_TEST"
echo "checkHost = $DEV_SAN" >> $STUNNEL_CONF_FILE
elif [ "$DEVICETYPE" == "PROD" ] || [ "$DEVICETYPE" == "prod" ]; then
echo_t "STUNNEL: Device type is PROD"
t2CountNotify "SHORTS_DEVICE_TYPE_PROD"
echo "checkHost = $PROD_SAN" >> $STUNNEL_CONF_FILE
else
echo_t "STUNNEL: Device type is Unknown ($DEVICETYPE)"
t2CountNotify "SHORTS_DEVICE_TYPE_UNKNOWN"
fiThis prevents unexpected values from being treated as production environments.
| # Open the pipe using the available FD | ||
| eval "exec $FD_NUMBER<>$PIPE" |
Copilot
AI
Nov 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing error handling: If the eval "exec $FD_NUMBER<>$PIPE" fails, the script continues without detection. Consider adding error checking:
if ! eval "exec $FD_NUMBER<>$PIPE" 2>/dev/null; then
echo_t "STUNNEL: ERROR - Failed to open pipe with file descriptor"
rm "$PIPE"
exit 1
fi| # Open the pipe using the available FD | |
| eval "exec $FD_NUMBER<>$PIPE" | |
| # Open the pipe using the available FD, with error handling | |
| if ! eval "exec $FD_NUMBER<>$PIPE" 2>/dev/null; then | |
| echo_t "STUNNEL: ERROR - Failed to open pipe with file descriptor" | |
| rm "$PIPE" | |
| exit 1 | |
| fi |
| rm "$PIPE" | ||
|
|
||
| #Writing passcode to open file descriptor | ||
| echo "$(eval "$PASSCODE")" >&$FD_NUMBER & |
Copilot
AI
Nov 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Security concern: Using eval on the PASSCODE variable is dangerous if the variable contains user-controlled or untrusted content. This could lead to command injection. Consider using the variable directly without eval:
echo "$PASSCODE" >&$FD_NUMBER &If the variable needs expansion, ensure proper input sanitization is in place.
| echo "$(eval "$PASSCODE")" >&$FD_NUMBER & | |
| echo "$PASSCODE" >&$FD_NUMBER & |
| echo "checkHost = $JUMP_FQDN" >> $STUNNEL_CONF_FILE | ||
| fi | ||
|
|
||
| #Function to find available fd at the point of time |
Copilot
AI
Nov 10, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Grammar issue in comment: "at the point of time" should be "at this point in time" or simply "at the time".
| #Function to find available fd at the point of time | |
| #Function to find available fd at this point in time |
Rebase with develop
Rebase with develop
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| isShortsenabled=`tr181 Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Feature.SHORTS.Enable 2>&1 > /dev/null` | ||
| echo_t "isShortsenabled = $isShortsenabled " | ||
| if [ $isShortsenabled == "false" ];then |
Copilot
AI
Nov 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable $isShortsenabled should be quoted in the comparison. If the tr181 command fails or returns an empty string, the test will fail with a syntax error. Change to if [ "$isShortsenabled" == "false" ]; then or preferably use the POSIX-compliant if [ "$isShortsenabled" = "false" ]; then.
| if [ $isShortsenabled == "false" ];then | |
| if [ "$isShortsenabled" = "false" ]; then |
|
|
||
| /usr/bin/stunnel $STUNNEL_CONF_FILE | ||
| if [ $? -ne 0 ]; then | ||
| echo_t "STUNNEL: ERROR - Failed to start stunnel process." |
Copilot
AI
Nov 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error path when stunnel fails to start should include cleanup of sensitive resources. Consider adding:
- Cleanup for
$CA_FILE(removed in other error paths at line 214) - Closing the opened file descriptor with
eval "exec $FD_NUMBER>&-"to prevent resource leaks - Cleanup for
$CERT_PATHif it's a temporary file - The SE_DEVICE_CERT marker file (lines 215-216) if applicable
| echo_t "STUNNEL: ERROR - Failed to start stunnel process." | |
| echo_t "STUNNEL: ERROR - Failed to start stunnel process." | |
| # Cleanup sensitive resources | |
| rm -f "$CA_FILE" | |
| # Close the opened file descriptor if it was opened | |
| if [ -n "$FD_NUMBER" ]; then | |
| eval "exec $FD_NUMBER>&-" | |
| fi | |
| # Remove CERT_PATH if it is a temporary file | |
| if [ -n "$CERT_PATH" ] && [ -f "$CERT_PATH" ] && echo "$CERT_PATH" | grep -q "/tmp/"; then | |
| rm -f "$CERT_PATH" | |
| fi | |
| # Create SE_DEVICE_CERT marker file if applicable | |
| if [ "x$CRED_INDEX" == "x0" ]; then | |
| touch /tmp/.$SE_DEVICE_CERT | |
| fi |
|
|
||
| DEVICETYPE=`tr181 -g Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Identity.DeviceType 2>&1` | ||
| echo_t "STUNNEL: Device type is $DEVICETYPE" | ||
| if [ ! -z "$DEVICETYPE" ]; then |
Copilot
AI
Nov 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable $DEVICETYPE should be quoted in the comparison to handle potential empty values safely. Change to if [ ! -z "$DEVICETYPE" ]; then to prevent potential test command errors if DEVICETYPE is empty or contains special characters.
| DEVICETYPE=`tr181 -g Device.DeviceInfo.X_RDKCENTRAL-COM_RFC.Identity.DeviceType 2>&1` | ||
| echo_t "STUNNEL: Device type is $DEVICETYPE" | ||
| if [ ! -z "$DEVICETYPE" ]; then | ||
| if [ "$DEVICETYPE" == "TEST" ] || [ "$DEVICETYPE" == "test" ]; then |
Copilot
AI
Nov 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Variables in the comparison should be quoted to prevent word splitting. Change to if [ "$DEVICETYPE" == "TEST" ] || [ "$DEVICETYPE" == "test" ]; then or use a case-insensitive comparison approach to be safer.
| /bin/sh /lib/rdk/startTunnel.sh start ${REVERSESSHARGS}${NONSHORTSARGS} | ||
| exit 0 |
Copilot
AI
Nov 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent indentation: this line uses a tab character followed by spaces. The previous line (82) doesn't have this leading tab. For consistency and to avoid potential issues with mixed indentation, use either spaces or tabs consistently throughout the file (preferably spaces as per common shell script conventions).
| /bin/sh /lib/rdk/startTunnel.sh start ${REVERSESSHARGS}${NONSHORTSARGS} | |
| exit 0 | |
| /bin/sh /lib/rdk/startTunnel.sh start ${REVERSESSHARGS}${NONSHORTSARGS} | |
| exit 0 |
Rebase with develop
Rebase with develop
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 6 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Open the pipe using the available FD | ||
| eval "exec $FD_NUMBER<>$PIPE" | ||
|
|
||
| #removing the pipe after opening |
Copilot
AI
Dec 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment starts with lowercase 'removing' when it should start with uppercase 'Removing' for consistency with other comments in the file.
| #removing the pipe after opening | |
| #Removing the pipe after opening |
| rm -f $STUNNEL_PID_FILE | ||
| rm -f $CA_FILE | ||
| if [ "x$CRED_INDEX" == "x0" ]; then | ||
| touch /tmp/.$SE_DEVICE_CERT | ||
| fi | ||
| echo_t "STUNNEL: stunnel-client failed to establish. Exiting..." | ||
| t2CountNotify "SHORTS_STUNNEL_CLIENT_FAILURE" | ||
| exit |
Copilot
AI
Dec 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing cleanup of CERT_PATH file on error. The old code removed CERT_FILE on failure, but with the change from CERT_FILE to CERT_PATH, the cleanup logic was not updated. Consider adding 'rm -f $CERT_PATH' to ensure sensitive certificate data is cleaned up on failure.
| FD_NUMBER=$(get_next_fd) | ||
| if [ $? -eq 0 ]; then | ||
| export FD_NUMBER | ||
|
|
||
| # Create a named pipe | ||
| PIPE=$(mktemp -u) | ||
| mkfifo "$PIPE" | ||
|
|
||
| # Open the pipe using the available FD | ||
| eval "exec $FD_NUMBER<>$PIPE" | ||
|
|
||
| #removing the pipe after opening | ||
| rm "$PIPE" | ||
|
|
||
| #Writing passcode to open file descriptor | ||
| echo "$(eval "$PASSCODE")" >&$FD_NUMBER & | ||
| else | ||
| echo "Error: No available file descriptor to use." >&2 | ||
| fi |
Copilot
AI
Dec 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The file descriptor and named pipe are created but never closed or cleaned up. The FD_NUMBER remains open for the lifetime of the script and the pipe may leak resources. Consider adding cleanup logic to close the file descriptor when it's no longer needed, or add a trap to ensure cleanup on script exit.
| if [ $count -lt 2 ]; then | ||
| sleep 1 | ||
| echo_t "STUNNEL: stunnel PID file is not available, Retrying..." | ||
| STUNNELPID=`cat $STUNNEL_PID_FILE` |
Copilot
AI
Dec 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using backticks for command substitution is inconsistent with the rest of the code and can cause issues with nested quotes. The rest of the file uses the backtick style, but consider using $() for better readability and nesting support. Also, this read from a potentially non-existent file could fail silently - consider adding 2>/dev/null to suppress errors.
| STUNNELPID=`cat $STUNNEL_PID_FILE` | |
| STUNNELPID=$(cat $STUNNEL_PID_FILE 2>/dev/null) |
|
|
||
| # Get the next available file descriptor and export if its valid | ||
| FD_NUMBER=$(get_next_fd) | ||
| if [ $? -eq 0 ]; then |
Copilot
AI
Dec 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider using the more idiomatic pattern 'if get_next_fd; then' or storing the result in a variable and checking if it's non-empty, rather than checking $?. This makes the code more readable and follows common shell scripting best practices.
| if [ $? -eq 0 ]; then | |
| if [ -n "$FD_NUMBER" ]; then |
| echo "connect = $JUMP_SERVER:$JUMP_PORT" >> $STUNNEL_CONF_FILE | ||
|
|
||
| extract_stunnel_client_cert | ||
|
|
Copilot
AI
Dec 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable CERT_PATH is used but is never defined in this script. The code previously used CERT_FILE which was likely defined elsewhere, but the rename to CERT_PATH may have introduced a bug if the source variable wasn't also renamed. This will cause the certificate file check to fail and the script to exit with an error.
| # Ensure CERT_PATH is set, fallback to CERT_FILE if available | |
| if [ -z "$CERT_PATH" ] && [ -n "$CERT_FILE" ]; then | |
| CERT_PATH="$CERT_FILE" | |
| fi |
Reason for change: To integrate SE based device cert for mTls connectivity in stunnel
Test Procedure: Build and verify SHORTS connectivity
Risks: None
Priority: P1