Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2a4814e

Browse files
authored
feat: add support for RDP URIs (#87)
Adds basic support for `coder:/` URIs for opening RDP.relates to#52 but I still need to add support for checking the authority.
1 parent119e52a commit2a4814e

File tree

8 files changed

+596
-86
lines changed

8 files changed

+596
-86
lines changed

‎App/App.xaml.cs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public partial class App : Application
4141
#endif
4242

4343
privatereadonlyILogger<App>_logger;
44+
privatereadonlyIUriHandler_uriHandler;
4445

4546
publicApp()
4647
{
@@ -72,6 +73,8 @@ public App()
7273
.Bind(builder.Configuration.GetSection(MutagenControllerConfigSection));
7374
services.AddSingleton<ISyncSessionController,MutagenController>();
7475
services.AddSingleton<IUserNotifier,UserNotifier>();
76+
services.AddSingleton<IRdpConnector,RdpConnector>();
77+
services.AddSingleton<IUriHandler,UriHandler>();
7578

7679
// SignInWindow views and view models
7780
services.AddTransient<SignInViewModel>();
@@ -98,6 +101,7 @@ public App()
98101

99102
_services=services.BuildServiceProvider();
100103
_logger=(ILogger<App>)_services.GetService(typeof(ILogger<App>))!;
104+
_uriHandler=(IUriHandler)_services.GetService(typeof(IUriHandler))!;
101105

102106
InitializeComponent();
103107
}
@@ -190,7 +194,19 @@ public void OnActivated(object? sender, AppActivationArguments args)
190194
_logger.LogWarning("URI activation with null data");
191195
return;
192196
}
193-
HandleURIActivation(protoArgs.Uri);
197+
198+
// don't need to wait for it to complete.
199+
_uriHandler.HandleUri(protoArgs.Uri).ContinueWith(t=>
200+
{
201+
if(t.Exception!=null)
202+
{
203+
// don't log query params, as they contain secrets.
204+
_logger.LogError(t.Exception,
205+
"unhandled exception while processing URI coder://{authority}{path}",
206+
protoArgs.Uri.Authority,protoArgs.Uri.AbsolutePath);
207+
}
208+
});
209+
194210
break;
195211

196212
caseExtendedActivationKind.AppNotification:
@@ -204,12 +220,6 @@ public void OnActivated(object? sender, AppActivationArguments args)
204220
}
205221
}
206222

207-
publicvoidHandleURIActivation(Uriuri)
208-
{
209-
// don't log the query string as that's where we include some sensitive information like passwords
210-
_logger.LogInformation("handling URI activation for {path}",uri.AbsolutePath);
211-
}
212-
213223
publicvoidHandleNotification(AppNotificationManager?sender,AppNotificationActivatedEventArgsargs)
214224
{
215225
// right now, we don't do anything other than log

‎App/Services/CredentialManager.cs

Lines changed: 141 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ public WindowsCredentialBackend(string credentialsTargetName)
307307

308308
publicTask<RawCredentials?>ReadCredentials(CancellationTokenct=default)
309309
{
310-
varraw=NativeApi.ReadCredentials(_credentialsTargetName);
310+
varraw=Wincred.ReadCredentials(_credentialsTargetName);
311311
if(raw==null)returnTask.FromResult<RawCredentials?>(null);
312312

313313
RawCredentials?credentials;
@@ -326,115 +326,179 @@ public WindowsCredentialBackend(string credentialsTargetName)
326326
publicTaskWriteCredentials(RawCredentialscredentials,CancellationTokenct=default)
327327
{
328328
varraw=JsonSerializer.Serialize(credentials,RawCredentialsJsonContext.Default.RawCredentials);
329-
NativeApi.WriteCredentials(_credentialsTargetName,raw);
329+
Wincred.WriteCredentials(_credentialsTargetName,raw);
330330
returnTask.CompletedTask;
331331
}
332332

333333
publicTaskDeleteCredentials(CancellationTokenct=default)
334334
{
335-
NativeApi.DeleteCredentials(_credentialsTargetName);
335+
Wincred.DeleteCredentials(_credentialsTargetName);
336336
returnTask.CompletedTask;
337337
}
338338

339-
privatestaticclassNativeApi
339+
}
340+
341+
/// <summary>
342+
/// Wincred provides relatively low level wrapped calls to the Wincred.h native API.
343+
/// </summary>
344+
internalstaticclassWincred
345+
{
346+
privateconstintCredentialTypeGeneric=1;
347+
privateconstintCredentialTypeDomainPassword=2;
348+
privateconstintPersistenceTypeLocalComputer=2;
349+
privateconstintErrorNotFound=1168;
350+
privateconstintCredMaxCredentialBlobSize=5*512;
351+
privateconststringPackageNTLM="NTLM";
352+
353+
publicstaticstring?ReadCredentials(stringtargetName)
340354
{
341-
privateconstintCredentialTypeGeneric=1;
342-
privateconstintPersistenceTypeLocalComputer=2;
343-
privateconstintErrorNotFound=1168;
344-
privateconstintCredMaxCredentialBlobSize=5*512;
355+
if(!CredReadW(targetName,CredentialTypeGeneric,0,outvarcredentialPtr))
356+
{
357+
varerror=Marshal.GetLastWin32Error();
358+
if(error==ErrorNotFound)returnnull;
359+
thrownewInvalidOperationException($"Failed to read credentials (Error{error})");
360+
}
345361

346-
publicstaticstring?ReadCredentials(stringtargetName)
362+
try
347363
{
348-
if(!CredReadW(targetName,CredentialTypeGeneric,0,outvarcredentialPtr))
349-
{
350-
varerror=Marshal.GetLastWin32Error();
351-
if(error==ErrorNotFound)returnnull;
352-
thrownewInvalidOperationException($"Failed to read credentials (Error{error})");
353-
}
364+
varcred=Marshal.PtrToStructure<CREDENTIALW>(credentialPtr);
365+
returnMarshal.PtrToStringUni(cred.CredentialBlob,cred.CredentialBlobSize/sizeof(char));
366+
}
367+
finally
368+
{
369+
CredFree(credentialPtr);
370+
}
371+
}
354372

355-
try
356-
{
357-
varcred=Marshal.PtrToStructure<CREDENTIAL>(credentialPtr);
358-
returnMarshal.PtrToStringUni(cred.CredentialBlob,cred.CredentialBlobSize/sizeof(char));
359-
}
360-
finally
373+
publicstaticvoidWriteCredentials(stringtargetName,stringsecret)
374+
{
375+
varbyteCount=Encoding.Unicode.GetByteCount(secret);
376+
if(byteCount>CredMaxCredentialBlobSize)
377+
thrownewArgumentOutOfRangeException(nameof(secret),
378+
$"The secret is greater than{CredMaxCredentialBlobSize} bytes");
379+
380+
varcredentialBlob=Marshal.StringToHGlobalUni(secret);
381+
varcred=newCREDENTIALW
382+
{
383+
Type=CredentialTypeGeneric,
384+
TargetName=targetName,
385+
CredentialBlobSize=byteCount,
386+
CredentialBlob=credentialBlob,
387+
Persist=PersistenceTypeLocalComputer,
388+
};
389+
try
390+
{
391+
if(!CredWriteW(refcred,0))
361392
{
362-
CredFree(credentialPtr);
393+
varerror=Marshal.GetLastWin32Error();
394+
thrownewInvalidOperationException($"Failed to write credentials (Error{error})");
363395
}
364396
}
365-
366-
publicstaticvoidWriteCredentials(stringtargetName,stringsecret)
397+
finally
367398
{
368-
varbyteCount=Encoding.Unicode.GetByteCount(secret);
369-
if(byteCount>CredMaxCredentialBlobSize)
370-
thrownewArgumentOutOfRangeException(nameof(secret),
371-
$"The secret is greater than{CredMaxCredentialBlobSize} bytes");
399+
Marshal.FreeHGlobal(credentialBlob);
400+
}
401+
}
372402

373-
varcredentialBlob=Marshal.StringToHGlobalUni(secret);
374-
varcred=newCREDENTIAL
375-
{
376-
Type=CredentialTypeGeneric,
377-
TargetName=targetName,
378-
CredentialBlobSize=byteCount,
379-
CredentialBlob=credentialBlob,
380-
Persist=PersistenceTypeLocalComputer,
381-
};
382-
try
383-
{
384-
if(!CredWriteW(refcred,0))
385-
{
386-
varerror=Marshal.GetLastWin32Error();
387-
thrownewInvalidOperationException($"Failed to write credentials (Error{error})");
388-
}
389-
}
390-
finally
391-
{
392-
Marshal.FreeHGlobal(credentialBlob);
393-
}
403+
publicstaticvoidDeleteCredentials(stringtargetName)
404+
{
405+
if(!CredDeleteW(targetName,CredentialTypeGeneric,0))
406+
{
407+
varerror=Marshal.GetLastWin32Error();
408+
if(error==ErrorNotFound)return;
409+
thrownewInvalidOperationException($"Failed to delete credentials (Error{error})");
394410
}
411+
}
412+
413+
publicstaticvoidWriteDomainCredentials(stringdomainName,stringserverName,stringusername,stringpassword)
414+
{
415+
vartargetName=$"{domainName}/{serverName}";
416+
vartargetInfo=newCREDENTIAL_TARGET_INFORMATIONW
417+
{
418+
TargetName=targetName,
419+
DnsServerName=serverName,
420+
DnsDomainName=domainName,
421+
PackageName=PackageNTLM,
422+
};
423+
varbyteCount=Encoding.Unicode.GetByteCount(password);
424+
if(byteCount>CredMaxCredentialBlobSize)
425+
thrownewArgumentOutOfRangeException(nameof(password),
426+
$"The secret is greater than{CredMaxCredentialBlobSize} bytes");
395427

396-
publicstaticvoidDeleteCredentials(stringtargetName)
428+
varcredentialBlob=Marshal.StringToHGlobalUni(password);
429+
varcred=newCREDENTIALW
397430
{
398-
if(!CredDeleteW(targetName,CredentialTypeGeneric,0))
431+
Type=CredentialTypeDomainPassword,
432+
TargetName=targetName,
433+
CredentialBlobSize=byteCount,
434+
CredentialBlob=credentialBlob,
435+
Persist=PersistenceTypeLocalComputer,
436+
UserName=username,
437+
};
438+
try
439+
{
440+
if(!CredWriteDomainCredentialsW(reftargetInfo,refcred,0))
399441
{
400442
varerror=Marshal.GetLastWin32Error();
401-
if(error==ErrorNotFound)return;
402-
thrownewInvalidOperationException($"Failed to delete credentials (Error{error})");
443+
thrownewInvalidOperationException($"Failed to write credentials (Error{error})");
403444
}
404445
}
446+
finally
447+
{
448+
Marshal.FreeHGlobal(credentialBlob);
449+
}
450+
}
405451

406-
[DllImport("Advapi32.dll",CharSet=CharSet.Unicode,SetLastError=true)]
407-
privatestaticexternboolCredReadW(stringtarget,inttype,intreservedFlag,outIntPtrcredentialPtr);
452+
[DllImport("Advapi32.dll",CharSet=CharSet.Unicode,SetLastError=true)]
453+
privatestaticexternboolCredReadW(stringtarget,inttype,intreservedFlag,outIntPtrcredentialPtr);
408454

409-
[DllImport("Advapi32.dll",CharSet=CharSet.Unicode,SetLastError=true)]
410-
privatestaticexternboolCredWriteW([In]refCREDENTIALuserCredential,[In]uintflags);
455+
[DllImport("Advapi32.dll",CharSet=CharSet.Unicode,SetLastError=true)]
456+
privatestaticexternboolCredWriteW([In]refCREDENTIALWuserCredential,[In]uintflags);
411457

412-
[DllImport("Advapi32.dll",SetLastError=true)]
413-
privatestaticexternvoidCredFree([In]IntPtrcred);
458+
[DllImport("Advapi32.dll",SetLastError=true)]
459+
privatestaticexternvoidCredFree([In]IntPtrcred);
414460

415-
[DllImport("Advapi32.dll",CharSet=CharSet.Unicode,SetLastError=true)]
416-
privatestaticexternboolCredDeleteW(stringtarget,inttype,intflags);
461+
[DllImport("Advapi32.dll",CharSet=CharSet.Unicode,SetLastError=true)]
462+
privatestaticexternboolCredDeleteW(stringtarget,inttype,intflags);
417463

418-
[StructLayout(LayoutKind.Sequential)]
419-
privatestructCREDENTIAL
420-
{
421-
publicintFlags;
422-
publicintType;
464+
[DllImport("Advapi32.dll",CharSet=CharSet.Unicode,SetLastError=true)]
465+
privatestaticexternboolCredWriteDomainCredentialsW([In]refCREDENTIAL_TARGET_INFORMATIONWtarget,[In]refCREDENTIALWuserCredential,[In]uintflags);
423466

424-
[MarshalAs(UnmanagedType.LPWStr)]publicstringTargetName;
467+
[StructLayout(LayoutKind.Sequential)]
468+
privatestructCREDENTIALW
469+
{
470+
publicintFlags;
471+
publicintType;
425472

426-
[MarshalAs(UnmanagedType.LPWStr)]publicstringComment;
473+
[MarshalAs(UnmanagedType.LPWStr)]publicstringTargetName;
427474

428-
publiclongLastWritten;
429-
publicintCredentialBlobSize;
430-
publicIntPtrCredentialBlob;
431-
publicintPersist;
432-
publicintAttributeCount;
433-
publicIntPtrAttributes;
475+
[MarshalAs(UnmanagedType.LPWStr)]publicstringComment;
434476

435-
[MarshalAs(UnmanagedType.LPWStr)]publicstringTargetAlias;
477+
publiclongLastWritten;
478+
publicintCredentialBlobSize;
479+
publicIntPtrCredentialBlob;
480+
publicintPersist;
481+
publicintAttributeCount;
482+
publicIntPtrAttributes;
436483

437-
[MarshalAs(UnmanagedType.LPWStr)]publicstringUserName;
438-
}
484+
[MarshalAs(UnmanagedType.LPWStr)]publicstringTargetAlias;
485+
486+
[MarshalAs(UnmanagedType.LPWStr)]publicstringUserName;
487+
}
488+
489+
[StructLayout(LayoutKind.Sequential)]
490+
privatestructCREDENTIAL_TARGET_INFORMATIONW
491+
{
492+
[MarshalAs(UnmanagedType.LPWStr)]publicstringTargetName;
493+
[MarshalAs(UnmanagedType.LPWStr)]publicstringNetbiosServerName;
494+
[MarshalAs(UnmanagedType.LPWStr)]publicstringDnsServerName;
495+
[MarshalAs(UnmanagedType.LPWStr)]publicstringNetbiosDomainName;
496+
[MarshalAs(UnmanagedType.LPWStr)]publicstringDnsDomainName;
497+
[MarshalAs(UnmanagedType.LPWStr)]publicstringDnsTreeName;
498+
[MarshalAs(UnmanagedType.LPWStr)]publicstringPackageName;
499+
500+
publicuintFlags;
501+
publicuintCredTypeCount;
502+
publicIntPtrCredTypes;
439503
}
440504
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp