Ich bin relativ neu in Socket-Programmierung, so dass dies wie eine sehr lahme Frage klingen mag. Ich muss authentifiziertes TCP (MD5 als eine TCP-Option zu Beginn) als Transport für eine Anwendung verwenden. Ich habe mich gefragt, ob dies mit der Sockets-API geschehen könnte oder ob es eine andere Form einer existierenden TCP-API gibt, mit der ich das gleiche machen könnte. Ich würde mich freuen, wenn ich dabei helfen könnte.Gibt es eine Möglichkeit, TCP-Optionen mithilfe der Sockets-API festzulegen?
Antwort
Ich bin ein bisschen verwirrt durch Ihre Frage. Sie können mit der setsockopt Funktion Socket-Optionen auf einem Socket setzen, aber durch den Klang des Rests Ihrer Frage ist das nicht ganz das, was Sie meinen. Ich habe noch nie von einem Transportprotokoll namens Authentifiziertes TCP gehört und google wirft nichts nützliches. Ist es ein Standard? Gibt es einen RFC?
Wenn Sie nur eine sichere, authentifizierte TCP-Transportschicht zu wollen, dann sollten Sie in schauen Sockets Layer Secure oder SSL kurz oder dessen Ersatz, Transport Layer Security oder TLS kurz. Es wird mit ziemlicher Sicherheit eine Implementierung für jede Sprache geben, die Sie verwenden (Sie haben dies nicht angegeben).
- Für C/C++ gibt es: OpenSSL
- Für .Net gibt es: SslStream
- Für Java gibt die Secure Socket Extensions
ist auch, was meinst du mit MD5 für die Authentifizierung? MD5 ist ein Hashalgorithmus, jedoch nicht kollisionsresistent genug für die Kommunikation, die sichere Signaturen erfordert.
Bearbeiten aha! Sie sprechen über TCP-Optionen, verstehe ich jetzt. Ich habe keine Implementierungen dieser speziellen TCP-Option gesehen, die in einer der Socket-APIs integriert ist, so dass Sie hier möglicherweise kein Glück haben. Es hängt von der Implementierung ab, die Sie verwenden, aber es kann besonders selten sein, da es sich um eine ziemlich obskure TCP-Option handelt, die das Border Gateway-Protokoll verbessert, nicht etwas, das Sie normalerweise außerhalb von Routing-Software verwenden würden. Für den Fall, es unterstützt wird, können Sie so etwas wie dies gesetzt, es würde:
BOOL optVal = TRUE;
int optLen = sizeof(BOOL);
if (setsockopt(
socket,
IPPROTO_TCP,
TCP_WHATEVER,
optVal,
optLen) != SOCKET_ERROR) {
printf("Success\n");
}
Wenn Sie für die TCP-MD5 Option beschrieben durch RFC 2385, einige Systeme wie FreeBSD unterstützen eine boolean TCP_MD5SIG Option suchen, dies zu ermöglichen. Es ist auf einem Sockel wie folgt aktiviert:
int opt = 1;
setsockopt(sockfd, IPPROTO_TCP, TCP_MD5SIG, &opt, sizeof(opt));
tcp(4)
für weitere Details.
Linux hat eine andere Version von diesem, die einen struct-Parameter verwendet; Die anderen Antworten hier haben einige zusätzliche Details.
Nun, das ist falsch. 'opt' ist kein int in dieser Sockopt. Es ist struct tcpm_addr. – user31986
@ user31986: oh danke, auf FreeBSD ist es eine boolesche Option, aber anscheinend verwendet es eine Struktur unter Linux. Ich habe die Antwort aktualisiert, um dies zu verdeutlichen. – mark4o
Diese Option kann auf keiner Plattform boolesch sein, da Sie auch einen Schlüssel angeben sollten. –
Ich habe gerade eine TCP-MD5-Verbindungsklasse in Ruby implementiert und dachte, dass dieses Code-Snippet jemand anderen die Mühe sparen könnte (zumindest jeder, der es unter Linux tut, wo die Einrichtung nicht dokumentiert ist). Das war nur von Kopfzeilen und Experimentieren; hoffentlich ist der Ruby für Leute, die in anderen Sprachen schreiben, nicht zu gruselig.
class TCPMD5Socket < Socket
IPPROTO_TCP = 6 # linux/in.h
TCP_MD5SIG = 14 # linux/tcp.h
TCP_MD5SIG_MAXKEYLEN = 80 # linux/tcp.h
# Works exactly the same as TCPSocket.open except you can supply a password
# to pass to the kernel for MD5 authhentication.
#
def initialize(host, port, password)
raise ArgumentError.new("Password is too long") if
password.length > TCP_MD5SIG_MAXKEYLEN
family = Socket.const_get(IPAddr.new(host).ipv4? ? "AF_INET" : "AF_INET6")
super(family, Socket::SOCK_STREAM, 0)
# struct tcp_md5sig {
# struct __kernel_sockaddr_storage tcpm_addr; /* address associated */
# __u16 __tcpm_pad1; /* zero */
# __u16 tcpm_keylen; /* key length */
# __u32 __tcpm_pad2; /* zero */
# __u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN]; /* key (binary) */
# };
tcp_md5sig_buffer = [
Socket.pack_sockaddr_in(port, host), 0, password.length, 0, password
].pack("a128SSLa#{TCP_MD5SIG_MAXKEYLEN}")
setsockopt(IPPROTO_TCP, TCP_MD5SIG, tcp_md5sig_buffer)
connect(Socket.pack_sockaddr_in(port, host))
end
end
Dies wird nicht, aber Linux 2.6.20 an auf etwas arbeiten, aber zumindest, wenn Sie stattdessen auf FreeBSD sind, ist es in einem man page beschrieben.Hier
ist die Nutzung für Linux: http://criticalindirection.com/2015/05/12/tcp_md5sig/
sockopt Struktur:
struct tcp_md5sig {
struct __kernel_sockaddr_storage tcpm_addr;
__u16 __tcpm_pad1;
__u16 tcpm_keylen;
__u32 __tcpm_pad2;
__u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN];
};
Die Linux-man-Seite hat keinen Hinweis, obwohl die Funktionalität im Kernel und libc vorhanden ist.
Aus dem Link:
Die Socket-Option TCP_MD5SIG speichert eine Abbildung der Pre-Shared-MD5-Schlüssel gegen den entsprechenden Peer-Endpunkt. Es ist zwingend erforderlich, den Client an eine bestimmte IP und einen bestimmten Port zu binden, die dem Server bekannt sind. Die Setsockopt() muss auf dem Listenet-Socket des Servers und dem Verbindungssocket des Clients aufgerufen werden, bevor die Verbindung() von Client aufgerufen wird.
Es hat auch volle Client-Server-Beispiel. Unten ist ein Schnipsel:
//Sockets Layer Call: bind()
memset((char *) &cl_addr, 0, sizeof(cl_addr));
cl_addr.sin6_family = AF_INET6;
if(inet_pton(AF_INET6, c6ip, &cl_addr.sin6_addr) <= 0)
error("ERROR on inet_pton");
cl_addr.sin6_port = htons(atoi(cport));
if (bind(sockfd, (struct sockaddr *) &cl_addr, sizeof(cl_addr)) < 0)
error("ERROR on binding");
memset((char *) &serv_addr, 0, sizeof(serv_addr));
serv_addr.sin6_family = AF_INET6;
if(inet_pton(AF_INET6, s6ip, &serv_addr.sin6_addr) <= 0)
error("ERROR on inet_pton");
serv_addr.sin6_port = htons(atoi(sport));
memcpy(&md5.tcpm_addr, &serv_addr, sizeof(serv_addr));
strcpy(md5.tcpm_key, key);
md5.tcpm_keylen = strlen(key);
if ((r = setsockopt(sockfd, IPPROTO_TCP, TCP_MD5SIG, &md5, sizeof(md5))) < 0)
error("listen setsockopt TCP_MD5SIG");
- 1. Gibt es eine Möglichkeit, einen separaten Kurztitel für UITabBar festzulegen?
- 2. Gibt es eine Möglichkeit, den Anwendungsnamen in Elmah programmgesteuert festzulegen?
- 3. Gibt es eine Möglichkeit, den Titel in showFeedDialog festzulegen?
- 4. Gibt es eine Möglichkeit, Tabulatorreihenfolge in ASP.net festzulegen?
- 5. Gibt es eine Möglichkeit, mysql-Variablen mithilfe des JDBC-Connectors festzulegen?
- 6. WebClient.AsyncDownloadString() - Gibt es eine Möglichkeit, ein Timeout festzulegen?
- 7. Gibt es eine Möglichkeit, den Namen einer Sytem.Threading.Task festzulegen?
- 8. Gibt es eine Möglichkeit, das erforderliche Attribut für text_field_tag festzulegen?
- 9. Gibt es eine Möglichkeit, automatische Eigenschaften in sekundären Konstruktoren festzulegen?
- 10. Angular2 gibt es eine Möglichkeit, Bootstrap col dynamisch festzulegen?
- 11. Gibt es keine einfache Möglichkeit, WPF-StatusBar-Text festzulegen?
- 12. Gibt es eine Möglichkeit, eine Ausführungsberechtigung für aufrufende Anwendungen für eine C# -Bibliothek festzulegen?
- 13. Gibt es eine Möglichkeit, die Textausrichtung der gesamten Spalte in einer Tabelle festzulegen?
- 14. Gibt es eine Möglichkeit, ServicePointManager die ServerCertificateValidationCallback-Eigenschaft aus der * .config-Datei deklarativ festzulegen?
- 15. Gibt es eine Möglichkeit, die Konfiguration auf Projektebene in WebStorm festzulegen?
- 16. Gibt es eine Möglichkeit, eine öffentliche (elastische) IP für eine Maschine in AWS festzulegen?
- 17. Gibt es eine Möglichkeit, die CSS-Informationen für eine bestimmte Instanz von YUI DataTable festzulegen?
- 18. Gibt es eine Möglichkeit, ein Memberlimit für eine neu sortierte Gruppe festzulegen?
- 19. Gibt es eine Möglichkeit, eine projekt- oder editorübergreifende Hervorhebungsebene anstatt pro Datei festzulegen?
- 20. Gibt es eine Möglichkeit, eine ElasticSearch-Dokument-ID beim Einfügen über AWS Kinesis Firehose manuell festzulegen?
- 21. Gibt es eine Möglichkeit, eine Präprozessorvariable auf den Wert einer Eigenschaft festzulegen?
- 22. Gibt es eine Möglichkeit, eine Eigenschaft/Attribut für einige/alle "sub" -Elemente festzulegen?
- 23. Inno-Setup: Gibt es eine Möglichkeit, einen Registrierungsschlüsselwert beim Deinstallieren festzulegen?
- 24. Gibt es eine Möglichkeit, die Priorität des von einem SwingWorker verwendeten Hintergrund-Threads festzulegen?
- 25. Gibt es eine Möglichkeit, den Wert von $ festzulegen? in einem Schein in Ruby?
- 26. Gibt es eine Möglichkeit, die Z-Reihenfolge festzulegen, wenn Sie MigLayout und die absolute Positionierung verwenden?
- 27. Gibt es eine Möglichkeit, die Ladepriorität von Bildern auf einer Site festzulegen?
- 28. Gibt es eine Möglichkeit, HttpExpires für ein Unterverzeichnis eines virtuellen Verzeichnisses programmgesteuert auf IIS 6 festzulegen?
- 29. Gibt es eine Möglichkeit, ASP.NET TextBox-Kennwort-Zeichen festzulegen, wenn Kennwort Textmodus?
- 30. HTML - Gibt es eine Möglichkeit, ein Zeitlimit für ein Datetime-lokales Element festzulegen?
Danke IRBMe! Ich beziehe mich auf RFC 2385. Um eine lange Geschichte kurz und auf der Grundlage der Art der Anwendung, müssen wir TCP mit MD5-Option als Transport (C-Implementierung) verwenden. Ich sehe Sockets API als eine mögliche Option, um diese Art von Transport einzurichten. Ich habe mich gefragt, ob es einen anderen API-Satz gibt, der dasselbe tun könnte, aber gleichzeitig die Implementierung ein wenig vereinfacht. danke! –