@@ -1095,7 +1095,8 @@ start_withno_pty(wchar_t *command)
1095
1095
PROCESS_INFORMATION pi ;
1096
1096
wchar_t cmd [MAX_CMD_LEN ];
1097
1097
SECURITY_ATTRIBUTES sa ;
1098
- BOOL ret ;
1098
+ BOOL ret , process_input = FALSE, run_under_cmd = FALSE;
1099
+ size_t command_len ;
1099
1100
char buf [128 ];
1100
1101
DWORD rd = 0 , wr = 0 , i = 0 ;
1101
1102
@@ -1124,16 +1125,60 @@ start_withno_pty(wchar_t *command)
1124
1125
GOTO_CLEANUP_ON_FALSE (SetHandleInformation (pipe_in , HANDLE_FLAG_INHERIT , 0 ));
1125
1126
GOTO_CLEANUP_ON_FALSE (SetHandleInformation (child_pipe_write , HANDLE_FLAG_INHERIT , 0 ));
1126
1127
1127
- /*TODO - pick this up from system32*/
1128
- cmd [0 ] = L'\0' ;
1129
- GOTO_CLEANUP_ON_ERR (wcscat_s (cmd , MAX_CMD_LEN , L"cmd.exe" ));
1128
+ /*
1129
+ * check if the input needs to be processed (ex for CRLF translation)
1130
+ * input stream needs to be processed when running the command
1131
+ * within shell processor. This is needed when
1132
+ * - launching a interactive shell (-nopty)
1133
+ * ssh -T user@target
1134
+ * - launching cmd explicity
1135
+ * ssh user@target cmd
1136
+ * - executing a cmd command
1137
+ * ssh user@target dir
1138
+ * - executing a cmd command within a cmd
1139
+ * ssh user@target cmd /c dir
1140
+ */
1141
+
1142
+ if (!command )
1143
+ process_input = TRUE;
1144
+ else {
1145
+ command_len = wcsnlen_s (command , MAX_CMD_LEN );
1146
+ if ((command_len >= 3 && wcsncmp (command , L"cmd" , 4 ) == 0 ) ||
1147
+ (command_len >= 7 && wcsncmp (command , L"cmd.exe" , 8 ) == 0 ) ||
1148
+ (command_len >= 4 && wcsncmp (command , L"cmd " , 4 ) == 0 ) ||
1149
+ (command_len >= 8 && wcsncmp (command , L"cmd.exe " , 8 ) == 0 ))
1150
+ process_input = TRUE;
1151
+ }
1152
+
1153
+ /* Try launching command as is first */
1130
1154
if (command ) {
1131
- GOTO_CLEANUP_ON_ERR (wcscat_s (cmd , MAX_CMD_LEN , L" /c" ));
1132
- GOTO_CLEANUP_ON_ERR (wcscat_s (cmd , MAX_CMD_LEN , L" " ));
1133
- GOTO_CLEANUP_ON_ERR (wcscat_s (cmd , MAX_CMD_LEN , command ));
1155
+ ret = CreateProcessW (NULL , command , NULL , NULL , TRUE, 0 , NULL , NULL , & si , & pi );
1156
+ if (ret == FALSE) {
1157
+ /* it was probably this case - ssh user@target dir */
1158
+ if (GetLastError () == ERROR_FILE_NOT_FOUND )
1159
+ run_under_cmd = TRUE;
1160
+ else
1161
+ goto cleanup ;
1162
+ }
1134
1163
}
1164
+ else
1165
+ run_under_cmd = TRUE;
1166
+
1167
+ /* if above failed with FILE_NOT_FOUND, try running the provided command under cmd*/
1168
+ if (run_under_cmd ) {
1169
+ /*TODO - pick this up from system32*/
1170
+ cmd [0 ] = L'\0' ;
1171
+ GOTO_CLEANUP_ON_ERR (wcscat_s (cmd , MAX_CMD_LEN , L"cmd.exe" ));
1172
+ if (command ) {
1173
+ GOTO_CLEANUP_ON_ERR (wcscat_s (cmd , MAX_CMD_LEN , L" /c" ));
1174
+ GOTO_CLEANUP_ON_ERR (wcscat_s (cmd , MAX_CMD_LEN , L" " ));
1175
+ GOTO_CLEANUP_ON_ERR (wcscat_s (cmd , MAX_CMD_LEN , command ));
1176
+ }
1135
1177
1136
- GOTO_CLEANUP_ON_FALSE (CreateProcess (NULL , cmd , NULL , NULL , TRUE, 0 , NULL , NULL , & si , & pi ));
1178
+ GOTO_CLEANUP_ON_FALSE (CreateProcessW (NULL , cmd , NULL , NULL , TRUE, 0 , NULL , NULL , & si , & pi ));
1179
+ /* Create process succeeded when running under cmd. input stream needs to be processed */
1180
+ process_input = TRUE;
1181
+ }
1137
1182
1138
1183
/* close unwanted handles*/
1139
1184
CloseHandle (child_pipe_read );
@@ -1152,6 +1197,12 @@ start_withno_pty(wchar_t *command)
1152
1197
rd = wr = i = 0 ;
1153
1198
GOTO_CLEANUP_ON_FALSE (ReadFile (pipe_in , buf , sizeof (buf )- 1 , & rd , NULL ));
1154
1199
1200
+ if (process_input == FALSE) {
1201
+ /* write stream directly to child stdin */
1202
+ GOTO_CLEANUP_ON_FALSE (WriteFile (child_pipe_write , buf , rd , & wr , NULL ));
1203
+ continue ;
1204
+ }
1205
+ /* else - process input before routing it to child */
1155
1206
while (i < rd ) {
1156
1207
/* skip arrow keys */
1157
1208
if ((rd - i >= 3 ) && (buf [i ] == '\033' ) && (buf [i + 1 ] == '[' ) &&
0 commit comments