'Using pscp in C# for file transfer between Windows and Linux through a post request

I have been trying to transfer files through a C# code, but it doesn't seem to work. Although the following line in command prompt works fine.

"C:\Program Files (x86)\PuTTY\pscp.exe" -l user -pw password C:\Users\user1\Desktop\\transfer1.txt 000.000.00.000:/home/doc

The communication class is

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;

namespace Server.Controllers
{     
    public class ComLinux
    {
        public static string TransferFilesToSever(string args)
        {
        Process p = new Process();

        p.StartInfo.FileName = @"C:\Program Files (x86)\PuTTY\pscp.exe";
        p.StartInfo.Arguments = args;
        p.StartInfo.UseShellExecute = false;
        p.StartInfo.RedirectStandardInput = true;
        p.StartInfo.RedirectStandardOutput = true;
        p.StartInfo.CreateNoWindow = false;
        p.Start();
        string output = p.StandardOutput.ReadToEnd();
        p.WaitForExit(); 
        return "Done";
   }}}

and the SendFilesController looks like

using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace Server.Controllers
{
    [Route("api/[controller]")]
    public class SendFilesController : Controller
    {
        [HttpPost]
        public IActionResult Post([FromBody] string cmdTostart)
        {
        var WindowsPath = ConfigurationManager.AppSettings["WindowsPath"].ToString();
        var LinuxPath = ConfigurationManager.AppSettings["LinuxPath"].ToString();
        var LinuxUserPass = ConfigurationManager.AppSettings["LinuxUserPass"].ToString();
        var WindowcommandtoL = LinuxUserPass + " " + WindowsPath + "transfer1.txt" + " " + LinuxPath;
        var resultw = ComLinux.TransferFilesToSever(WindowcommandtoL); 
        return Content("OK");
    }}}

And in app.config, I have

<add key="LinuxUserPass" value="-l user -pw password"/>
<add key="WindowsPath" value="C:\Users\user1\Desktop\"/>
<add key="LinuxPath" value="000.00.000://home/doc"/>

When a post request is made, the HTTP code is 200 but the file is not moving to the Linux server. I am not sure what is going wrong here.

The code seems to work when I am running it in debug mode via IIS Express at localhost:49595. But is is not working once I publish it to a website. p.Exitcode is 1 and p.ouput is blank.



Solution 1:[1]

First, it's wrong to use an external application for SCP upload.

Use some native .NET SCP implementation instead. See Library to do SCP for C#.


Anyway, one obvious problem is that your command does not include -hostkey switch. You need to verify SSH host key fingerprint. If you have ever connected with PuTTY/PSCP, you got prompted to verify the hostkey. If you did, the verified hostkey is cached in Windows registry. That's why your code works, when executed on your local machine using your local account.

But if you run the code on another machine or using another account, it won't work as the host key is not verified there.

You should include the -hostkey switch with your host key fingerprint.

Solution 2:[2]

The reason why I was unable to send files was that the Application Pool identity was default and I had to change it to my user name.

Although I decided to not use pscp and instead use ssh.net library. Thanks a lot to Martin Prikryl

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 anse15