@@ -1179,42 +1179,59 @@ static int wolfSSH_SFTP_RecvRealPath(WOLFSSH* ssh, int reqId, byte* data,
11791179 r [rSz ] = '\0' ;
11801180 WLOG (WS_LOG_SFTP , "Real Path Request = %s" , r );
11811181
1182- if (ssh -> sftpDefaultPath != NULL ) {
1183- ret = wolfSSH_RealPath (ssh -> sftpDefaultPath , r , s , sizeof s );
1184- }
1185- else {
1182+ /* If the default path isn't set, try to get it. */
1183+ if (ssh -> sftpDefaultPath == NULL ) {
11861184 char wd [WOLFSSH_MAX_FILENAME ];
11871185 WMEMSET (wd , 0 , WOLFSSH_MAX_FILENAME );
1186+ ret = WS_SUCCESS ;
1187+
11881188 #ifndef USE_WINDOWS_API
1189- if (WGETCWD (ssh -> fs , wd , WOLFSSH_MAX_FILENAME ) == NULL ) {
1190- WLOG (WS_LOG_SFTP , "Unable to get current working directory" );
1191- if (wolfSSH_SFTP_CreateStatus (ssh , WOLFSSH_FTP_FAILURE , reqId ,
1192- "Directory error" , "English" , NULL , & outSz )
1193- != WS_SIZE_ONLY ) {
1194- return WS_FATAL_ERROR ;
1195- }
1196- out = (byte * ) WMALLOC (outSz , ssh -> ctx -> heap , DYNTYPE_BUFFER );
1197- if (out == NULL ) {
1198- return WS_MEMORY_E ;
1199- }
1200- if (wolfSSH_SFTP_CreateStatus (ssh , WOLFSSH_FTP_FAILURE , reqId ,
1201- "Directory error" , "English" , out , & outSz )
1202- != WS_SUCCESS ) {
1203- WFREE (out , ssh -> ctx -> heap , DYNTYPE_BUFFER );
1204- return WS_FATAL_ERROR ;
1205- }
1206- /* take over control of buffer */
1207- wolfSSH_SFTP_RecvSetSend (ssh , out , outSz );
1208- return WS_BAD_FILE_E ;
1209- }
1189+ if (WGETCWD (ssh -> fs , wd , sizeof (wd )- 1 ) == NULL ) {
1190+ ret = WS_INVALID_PATH_E ;
1191+ }
1192+ #else
1193+ if (GetCurrentDirectoryA (sizeof (wd )- 1 , wd ) == 0 ) {
1194+ ret = WS_INVALID_PATH_E ;
1195+ }
12101196 #endif
1211- ret = wolfSSH_RealPath (wd , r , s , sizeof s );
1197+
1198+ if (ret == WS_SUCCESS ) {
1199+ wd [sizeof (wd ) - 1 ] = 0 ;
1200+ ret = wolfSSH_RealPath (NULL , wd , s , sizeof s );
1201+ }
1202+ if (ret == WS_SUCCESS ) {
1203+ ret = wolfSSH_SFTP_SetDefaultPath (ssh , s );
1204+ }
1205+ }
1206+
1207+ /* If the default path still isn't set, send error to peer. */
1208+ if (ssh -> sftpDefaultPath == NULL ) {
1209+ WLOG (WS_LOG_SFTP , "Unable to get current working directory" );
1210+ if (wolfSSH_SFTP_CreateStatus (ssh , WOLFSSH_FTP_FAILURE , reqId ,
1211+ "Directory error" , "English" , NULL , & outSz )
1212+ != WS_SIZE_ONLY ) {
1213+ return WS_FATAL_ERROR ;
1214+ }
1215+ out = (byte * ) WMALLOC (outSz , ssh -> ctx -> heap , DYNTYPE_BUFFER );
1216+ if (out == NULL ) {
1217+ return WS_MEMORY_E ;
1218+ }
1219+ if (wolfSSH_SFTP_CreateStatus (ssh , WOLFSSH_FTP_FAILURE , reqId ,
1220+ "Directory error" , "English" , out , & outSz )
1221+ != WS_SUCCESS ) {
1222+ WFREE (out , ssh -> ctx -> heap , DYNTYPE_BUFFER );
1223+ return WS_FATAL_ERROR ;
1224+ }
1225+ /* take over control of buffer */
1226+ wolfSSH_SFTP_RecvSetSend (ssh , out , outSz );
1227+ return ret ;
12121228 }
1213- sSz = (word32 )WSTRLEN (s );
12141229
1230+ ret = wolfSSH_RealPath (ssh -> sftpDefaultPath , r , s , sizeof s );
12151231 if (ret != WS_SUCCESS ) {
1216- return WS_ERROR ;
1232+ return ret ;
12171233 }
1234+ sSz = (word32 )WSTRLEN (s );
12181235
12191236 WLOG (WS_LOG_SFTP , "Real Path Directory = %s" , s );
12201237
@@ -1570,7 +1587,8 @@ static int GetAndCleanPath(const char* defaultPath,
15701587{
15711588 char r [WOLFSSH_MAX_FILENAME ];
15721589
1573- if (sz > sizeof r ) sz = sizeof r ;
1590+ if (sz >= sizeof r )
1591+ return WS_BUFFER_E ;
15741592 WMEMCPY (r , data , sz );
15751593 r [sz ] = '\0' ;
15761594
@@ -1881,9 +1899,10 @@ int wolfSSH_SFTP_RecvOpen(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
18811899 return WS_BUFFER_E ;
18821900 }
18831901
1884- if (GetAndCleanPath (ssh -> sftpDefaultPath ,
1885- data + idx , sz , dir , sizeof (dir )) < 0 ) {
1886- return WS_BUFFER_E ;
1902+ ret = GetAndCleanPath (ssh -> sftpDefaultPath , data + idx , sz ,
1903+ dir , sizeof (dir ));
1904+ if (ret < 0 ) {
1905+ return ret ;
18871906 }
18881907 idx += sz ;
18891908
@@ -2156,7 +2175,7 @@ int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
21562175 }
21572176
21582177 if (WOPENDIR (ssh -> fs , ssh -> ctx -> heap , & ctx , dir ) != 0 ) {
2159- WLOG (WS_LOG_SFTP , "Error with opening directory" );
2178+ WLOG (WS_LOG_SFTP , "Error with opening directory: %s" , dir );
21602179 if (wolfSSH_SFTP_CreateStatus (ssh , WOLFSSH_FTP_NOFILE , reqId ,
21612180 "Unable To Open Directory" , "English" , NULL , & outSz )
21622181 != WS_SIZE_ONLY ) {
@@ -2304,7 +2323,7 @@ int wolfSSH_SFTP_RecvOpenDir(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
23042323 realName , sizeof (realName ), & isDir , ssh -> ctx -> heap );
23052324 if (findHandle == INVALID_HANDLE_VALUE || !isDir ) {
23062325
2307- WLOG (WS_LOG_SFTP , "Error with opening directory" );
2326+ WLOG (WS_LOG_SFTP , "Error with opening directory: %s" , name );
23082327 WFREE (dirName , ssh -> ctx -> heap , DYNTYPE_BUFFER );
23092328
23102329 if (wolfSSH_SFTP_CreateStatus (ssh , WOLFSSH_FTP_NOFILE , reqId ,
@@ -2545,16 +2564,26 @@ static int wolfSSH_SFTPNAME_readdir(WOLFSSH* ssh, WDIR* dir, WS_SFTPNAME* out,
25452564 char r [WOLFSSH_MAX_FILENAME ];
25462565 char s [WOLFSSH_MAX_FILENAME ];
25472566
2548- r [0 ] = '\0' ;
25492567 if (!special ) { /* do not add dir name in special case */
2550- WSTRNCAT (r , dirName , sizeof (r ));
2551- WSTRNCAT (r , "/" , sizeof (r ));
2568+ if (WSTRLEN (dirName ) + out -> fSz + 2 > (sizeof r )) {
2569+ WLOG (WS_LOG_SFTP , "Path length too large" );
2570+ WFREE (out -> fName , out -> heap , DYNTYPE_SFTP );
2571+ return WS_FATAL_ERROR ;
2572+ }
2573+ WSNPRINTF (r , sizeof (r ), "%s/%s" , dirName , out -> fName );
2574+ }
2575+ else {
2576+ if (out -> fSz + 1 > (sizeof r )) {
2577+ WLOG (WS_LOG_SFTP , "Path length too large" );
2578+ WFREE (out -> fName , out -> heap , DYNTYPE_SFTP );
2579+ return WS_FATAL_ERROR ;
2580+ }
2581+ WSTRNCPY (r , out -> fName , sizeof (r ));
25522582 }
2553- WSTRNCAT (r , out -> fName , sizeof (r ));
2554- r [sizeof (r ) - 1 ] = 0 ;
25552583
25562584 if (wolfSSH_RealPath (ssh -> sftpDefaultPath , r , s , sizeof (s )) < 0 ) {
25572585 WLOG (WS_LOG_SFTP , "Error cleaning path to get attributes" );
2586+ WFREE (out -> fName , out -> heap , DYNTYPE_SFTP );
25582587 return WS_FATAL_ERROR ;
25592588 }
25602589
@@ -2626,13 +2655,16 @@ static int wolfSSH_SFTPNAME_readdir(WOLFSSH* ssh, WDIR* dir, WS_SFTPNAME* out,
26262655 char r [WOLFSSH_MAX_FILENAME ];
26272656 char s [WOLFSSH_MAX_FILENAME ];
26282657
2629- r [0 ] = '\0' ;
2630- WSTRNCAT (r , dirName , sizeof (r ));
2631- WSTRNCAT (r , "/" , sizeof (r ));
2632- WSTRNCAT (r , out -> fName , sizeof (r ));
2633- r [sizeof (r ) - 1 ] = 0 ;
2658+ if ((WSTRLEN (dirName ) + WSTRLEN (out -> fName ) + 2 ) > sizeof (r )) {
2659+ WLOG (WS_LOG_SFTP , "Path length too large" );
2660+ WFREE (out -> fName , out -> heap , DYNTYPE_SFTP );
2661+ return WS_FATAL_ERROR ;
2662+ }
2663+ WSNPRINTF (r , sizeof (r ), "%s/%s" , dirName , out -> fName );
26342664
26352665 if (wolfSSH_RealPath (ssh -> sftpDefaultPath , r , s , sizeof (s )) < 0 ) {
2666+ WLOG (WS_LOG_SFTP , "Error cleaning path to get attributes" );
2667+ WFREE (out -> fName , out -> heap , DYNTYPE_SFTP );
26362668 return WS_FATAL_ERROR ;
26372669 }
26382670
@@ -2722,26 +2754,18 @@ static int wolfSSH_SFTPNAME_readdir(WOLFSSH* ssh, WDIR* dir, WS_SFTPNAME* out,
27222754 int bufSz ;
27232755 int tmpSz ;
27242756
2725- bufSz = out -> fSz + (int )WSTRLEN (dirName ) + sizeof ( WS_DELIM );
2726- buf = (char * )WMALLOC (bufSz + 1 , out -> heap , DYNTYPE_SFTP );
2757+ bufSz = out -> fSz + (int )WSTRLEN (dirName ) + 2 ; /* /+nul */
2758+ buf = (char * )WMALLOC (bufSz , out -> heap , DYNTYPE_SFTP );
27272759 if (buf == NULL ) {
2760+ WFREE (out -> fName , out -> heap , DYNTYPE_SFTP );
27282761 return WS_MEMORY_E ;
27292762 }
2730- buf [0 ] = '\0' ;
2731- if (!special ) {
2732- WSTRNCAT (buf , dirName , bufSz + 1 );
2733- tmpSz = (int )WSTRLEN (buf );
27342763
2735- /* add delimiter between path and file/dir name */
2736- if (tmpSz + 1 < bufSz ) {
2737- buf [tmpSz ] = WS_DELIM ;
2738- buf [tmpSz + 1 ] = '\0' ;
2739- }
2740- WSTRNCAT (buf , out -> fName , bufSz + 1 );
2764+ if (!special ) {
2765+ WSNPRINTF (buf , bufSz , "%s/%s" , dirName , out -> fName );
27412766 }
27422767 else {
2743- WSTRNCAT (buf , realFileName , bufSz + 1 );
2744- WSTRNCAT (buf , "\\" , bufSz + 1 );
2768+ WSNPRINTF (buf , bufSz , "%s/" , realFileName );
27452769 }
27462770 if (SFTP_GetAttributes (ssh -> fs , buf , & out -> atrb , 0 , ssh -> ctx -> heap )
27472771 != WS_SUCCESS ) {
@@ -2797,13 +2821,16 @@ static int wolfSSH_SFTPNAME_readdir(WOLFSSH* ssh, WDIR* dir, WS_SFTPNAME* out,
27972821 char r [WOLFSSH_MAX_FILENAME ];
27982822 char s [WOLFSSH_MAX_FILENAME ];
27992823
2800- r [0 ] = '\0' ;
2801- WSTRNCAT (r , dirName , sizeof (r ));
2802- WSTRNCAT (r , "/" , sizeof (r ));
2803- WSTRNCAT (r , out -> fName , sizeof (r ));
2804- r [sizeof (r ) - 1 ] = 0 ;
2824+ if ((WSTRLEN (dirName ) + WSTRLEN (out -> fName ) + 2 ) > sizeof (r )) {
2825+ WLOG (WS_LOG_SFTP , "Path length too large" );
2826+ WFREE (out -> fName , out -> heap , DYNTYPE_SFTP );
2827+ return WS_FATAL_ERROR ;
2828+ }
2829+ WSNPRINTF (r , sizeof (r ), "%s/%s" , dirName , out -> fName );
28052830
28062831 if (wolfSSH_RealPath (ssh -> sftpDefaultPath , r , s , sizeof (s )) < 0 ) {
2832+ WLOG (WS_LOG_SFTP , "Error cleaning path to get attributes" );
2833+ WFREE (out -> fName , out -> heap , DYNTYPE_SFTP );
28072834 return WS_FATAL_ERROR ;
28082835 }
28092836 if (SFTP_GetAttributes (ssh -> fs , s , & out -> atrb , 0 , ssh -> ctx -> heap )
@@ -2861,13 +2888,16 @@ static int wolfSSH_SFTPNAME_readdir(WOLFSSH* ssh, WDIR* dir, WS_SFTPNAME* out,
28612888 char r [WOLFSSH_MAX_FILENAME ];
28622889 char s [WOLFSSH_MAX_FILENAME ];
28632890
2864- r [0 ] = '\0' ;
2865- WSTRNCAT (r , dirName , sizeof (r ));
2866- WSTRNCAT (r , "/" , sizeof (r ));
2867- WSTRNCAT (r , out -> fName , sizeof (r ));
2868- r [sizeof (r ) - 1 ] = 0 ;
2891+ if ((WSTRLEN (dirName ) + WSTRLEN (out -> fName ) + 2 ) > sizeof (r )) {
2892+ WLOG (WS_LOG_SFTP , "Path length too large" );
2893+ WFREE (out -> fName , out -> heap , DYNTYPE_SFTP );
2894+ return WS_FATAL_ERROR ;
2895+ }
2896+ WSNPRINTF (r , sizeof (r ), "%s/%s" , dirName , out -> fName );
28692897
28702898 if (wolfSSH_RealPath (ssh -> sftpDefaultPath , r , s , sizeof (s )) < 0 ) {
2899+ WFREE (out -> fName , out -> heap , DYNTYPE_SFTP );
2900+ WLOG (WS_LOG_SFTP , "Error cleaning path to get attributes" );
28712901 return WS_FATAL_ERROR ;
28722902 }
28732903
@@ -3739,10 +3769,8 @@ int wolfSSH_SFTP_RecvRemove(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
37393769 return WS_BUFFER_E ;
37403770 }
37413771
3742- if (GetAndCleanPath (ssh -> sftpDefaultPath , data + idx , sz ,
3743- name , sizeof (name )) < 0 ) {
3744- ret = WS_BAD_FILE_E ;
3745- }
3772+ ret = GetAndCleanPath (ssh -> sftpDefaultPath , data + idx , sz ,
3773+ name , sizeof (name ));
37463774
37473775 if (ret == WS_SUCCESS ) {
37483776 #ifndef USE_WINDOWS_API
@@ -3826,19 +3854,21 @@ int wolfSSH_SFTP_RecvRename(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
38263854 if (sz > maxSz - idx ) {
38273855 ret = WS_BUFFER_E ;
38283856 }
3829- if (GetAndCleanPath ( ssh -> sftpDefaultPath ,
3830- data + idx , sz , old , sizeof ( old )) < 0 ) {
3831- ret = WS_FATAL_ERROR ;
3857+ if (ret == WS_SUCCESS ) {
3858+ ret = GetAndCleanPath ( ssh -> sftpDefaultPath , data + idx , sz ,
3859+ old , sizeof ( old )) ;
38323860 }
3833- idx += sz ;
3834- /* get new file name */
3835- ato32 (data + idx , & sz ); idx += UINT32_SZ ;
3836- if (sz > maxSz - idx ) {
3837- ret = WS_BUFFER_E ;
3861+ if (ret == WS_SUCCESS ) {
3862+ idx += sz ;
3863+ /* get new file name */
3864+ ato32 (data + idx , & sz ); idx += UINT32_SZ ;
3865+ if (sz > maxSz - idx ) {
3866+ ret = WS_BUFFER_E ;
3867+ }
38383868 }
3839- if (GetAndCleanPath ( ssh -> sftpDefaultPath ,
3840- data + idx , sz , name , sizeof ( name )) < 0 ) {
3841- ret = WS_BUFFER_E ;
3869+ if (ret == WS_SUCCESS ) {
3870+ ret = GetAndCleanPath ( ssh -> sftpDefaultPath , data + idx , sz ,
3871+ name , sizeof ( name )) ;
38423872 }
38433873
38443874 if (ret == WS_SUCCESS ) {
0 commit comments