Ich versuche ein C-Programm, um OAuth 2 Authcode von Google Server (in Form einer HTTP-GET-Anfrage) zu akzeptieren. Wenn ich versuche, recv() zu lesen, wird der Fehler ausgegeben. Der Transportendpunkt ist nicht verbunden. Dies ist nur, nachdem ich eine nicht negative ganze Zahl nach dem Aufruf von accept() erhalten habe. Ich habe das gleiche mit Java und Netcat-Dienstprogramm versucht, beide funktionieren gut für mich.Socket geschlossen vor recv ohne Aufruf zu schließen
Hier ist der Code.
#include<stdio.h>
#include<string.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<stdlib.h>
#include<pthread.h>
#include<sys/select.h>
#include<fcntl.h>
#include<errno.h>
void *send_authcode_request(void *sockaddr_ptr);
int main() {
char *bind_addr = "127.0.0.1";
char *errmsg = (char *) malloc(1024);
short int port = 0;
setvbuf(stdout, NULL, _IONBF, 0);
struct sockaddr_in local_addr;
struct sockaddr_in client_addr;
local_addr.sin_family = AF_INET;
local_addr.sin_port = port;
inet_aton(bind_addr, &(local_addr.sin_addr));
memset(&(local_addr.sin_zero), '\0', 8);
int sock_id = socket(AF_INET, SOCK_STREAM, 0);
/*fcntl(sock_id, F_SETFL, O_NONBLOCK);*/
if (bind(sock_id, (struct sockaddr*) &local_addr, sizeof(struct sockaddr)) == -1) {
sprintf(errmsg, "Cannot bind socket to the port #%d", port);
perror(errmsg);
return -1;
}
if (listen(sock_id, 20) == -1) {
sprintf(errmsg, "Cannot listen to connections on the socket");
perror(errmsg);
return -1;
}
int sin_size = sizeof(struct sockaddr_in);
if(getsockname(sock_id, (struct sockaddr *) &local_addr, &sin_size) == -1) {
sprintf(errmsg, "Unable to get the current address of the socket");
perror(errmsg);
return -1;
}
printf("\n Port no after binding #%d\n", ntohs(local_addr.sin_port));
pthread_t authcode_req_thread;
pthread_create(&authcode_req_thread, NULL, send_authcode_request, (void *) &local_addr);
fd_set read_fs;
FD_ZERO(&read_fs);
FD_SET(sock_id, &read_fs);
long accept_timeout = 60*10;
struct timeval tv;
tv.tv_sec = accept_timeout;
tv.tv_usec = 0;
char auth_code_info[1024];
if (select(sock_id+1, &read_fs, NULL, NULL, &tv) > 0) {
/*if(accept4(sock_id, (struct sockaddr *) &client_addr, &sin_size, SOCK_NONBLOCK) == -1) {*/
if(accept(sock_id, (struct sockaddr *) &client_addr, &sin_size) >= 0) {
/* Accept auth code */
int bytesread;
if ((bytesread = recv(sock_id, auth_code_info, 1023, 0)) == -1) {
perror(errmsg);
return -1;
}
printf("\n%s\n", auth_code_info);
char *reply = "Done! You can now close the window";
send(sock_id, reply, strlen(reply), 0);
} else {
sprintf(errmsg, "No client connected within timeout of %ld seconds", accept_timeout);
perror(errmsg);
return -1;
}
} else {
sprintf(errmsg, "No client connected within timeout of %ld seconds", accept_timeout);
perror(errmsg);
return -1;
}
close(sock_id);
printf("\n");
return 0;
}
void *send_authcode_request(void *ptr) {
char *scope = "https://www.googleapis.com/auth/drive";
char *client_id = "1098482466406-c3h15ld90l03s0pl4rm7qq54fcb49t78.apps.googleusercontent.com";
const char *temp_authcode_uri = "xdg-open \"https://accounts.google.com/o/oauth2/v2/auth?scope=%s&redirect_uri=http://127.0.0.1:%d&response_type=code&client_id=%s\"";
struct sockaddr_in *socket_address = (struct sockaddr_in *) ptr;
int max_authcode_uri_len = strlen(temp_authcode_uri) + strlen(client_id) + strlen(scope);
char *authcode_uri = (char *) malloc(max_authcode_uri_len);
sprintf(authcode_uri, temp_authcode_uri, scope, ntohs(socket_address->sin_port), client_id);
printf("\n%s\n", authcode_uri);
system(authcode_uri);
}
Allerdings, wenn ich auf den gleichen Port netcat, hören zeigt es die HTTP-Anforderung vom Browser. Also habe ich den TCP-Verkehr für den Port mit Wireshark verfolgt und einen anderen Verkehr gefunden als den, den ich bei Verwendung von netcat erhalte.
Für mein Programm
No. Time Source Destination Protocol Length Info
1 0.000000000 127.0.0.1 127.0.0.1 TCP 74 48234 → 49927 [SYN] Seq=0 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=7268636 TSecr=0 WS=128
2 0.000010715 127.0.0.1 127.0.0.1 TCP 74 49927 → 48234 [SYN, ACK] Seq=0 Ack=1 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=7268636 TSecr=7268636 WS=128
3 0.000020978 127.0.0.1 127.0.0.1 TCP 66 48234 → 49927 [ACK] Seq=1 Ack=1 Win=43776 Len=0 TSval=7268636 TSecr=7268636
4 0.000059901 127.0.0.1 127.0.0.1 TCP 74 48236 → 49927 [SYN] Seq=0 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=7268636 TSecr=0 WS=128
5 0.000064624 127.0.0.1 127.0.0.1 TCP 74 49927 → 48236 [SYN, ACK] Seq=0 Ack=1 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=7268636 TSecr=7268636 WS=128
6 0.000070536 127.0.0.1 127.0.0.1 TCP 66 48236 → 49927 [ACK] Seq=1 Ack=1 Win=43776 Len=0 TSval=7268636 TSecr=7268636
7 0.000384302 127.0.0.1 127.0.0.1 TCP 66 49927 → 48234 [FIN, ACK] Seq=1 Ack=1 Win=43776 Len=0 TSval=7268636 TSecr=7268636
8 0.000412860 127.0.0.1 127.0.0.1 TCP 66 49927 → 48236 [RST, ACK] Seq=1 Ack=1 Win=43776 Len=0 TSval=7268636 TSecr=7268636
9 0.000997709 127.0.0.1 127.0.0.1 TCP 66 48234 → 49927 [FIN, ACK] Seq=1 Ack=2 Win=43776 Len=0 TSval=7268637 TSecr=7268636
10 0.000974316 127.0.0.1 127.0.0.1 TCP 66 [TCP Keep-Alive] 48234 → 49927 [ACK] Seq=1 Ack=2 Win=43776 Len=0 TSval=7268637 TSecr=7268636
11 0.001005630 127.0.0.1 127.0.0.1 TCP 66 49927 → 48234 [ACK] Seq=2 Ack=2 Win=43776 Len=0 TSval=7268637 TSecr=7268637
12 0.001047174 127.0.0.1 127.0.0.1 TCP 74 48238 → 49927 [SYN] Seq=0 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=7268637 TSecr=0 WS=128
13 0.001051855 127.0.0.1 127.0.0.1 TCP 54 49927 → 48238 [RST, ACK] Seq=1 Ack=1 Win=0 Len=0
14 0.237652758 127.0.0.1 127.0.0.1 TCP 74 48240 → 49927 [SYN] Seq=0 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=7268696 TSecr=0 WS=128
15 0.237664760 127.0.0.1 127.0.0.1 TCP 54 49927 → 48240 [RST, ACK] Seq=1 Ack=1 Win=0 Len=0
16 5.243733213 127.0.0.1 127.0.0.1 TCP 74 48242 → 49927 [SYN] Seq=0 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=7269947 TSecr=0 WS=128
17 5.243751969 127.0.0.1 127.0.0.1 TCP 54 49927 → 48242 [RST, ACK] Seq=1 Ack=1 Win=0 Len=0
wenn netcat
Mit netcat verwenden, erhalte ich die benötigte HTTP-Get-Anfrage die Authentifizierungs-Token enthält.
No. Time Source Destination Protocol Length Info
1 0.000000000 127.0.0.1 127.0.0.1 TCP 74 45064 → 2807 [SYN] Seq=0 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=7233868 TSecr=0 WS=128
2 0.000008155 127.0.0.1 127.0.0.1 TCP 74 2807 → 45064 [SYN, ACK] Seq=0 Ack=1 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=7233868 TSecr=7233868 WS=128
3 0.000015895 127.0.0.1 127.0.0.1 TCP 66 45064 → 2807 [ACK] Seq=1 Ack=1 Win=43776 Len=0 TSval=7233868 TSecr=7233868
4 0.000043941 127.0.0.1 127.0.0.1 TCP 74 45066 → 2807 [SYN] Seq=0 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=7233868 TSecr=0 WS=128
5 0.000047566 127.0.0.1 127.0.0.1 TCP 74 2807 → 45066 [SYN, ACK] Seq=0 Ack=1 Win=43690 Len=0 MSS=65495 SACK_PERM=1 TSval=7233868 TSecr=7233868 WS=128
6 0.000050911 127.0.0.1 127.0.0.1 TCP 66 45066 → 2807 [ACK] Seq=1 Ack=1 Win=43776 Len=0 TSval=7233868 TSecr=7233868
7 0.000074583 127.0.0.1 127.0.0.1 TCP 66 2807 → 45066 [RST, ACK] Seq=1 Ack=1 Win=43776 Len=0 TSval=7233868 TSecr=7233868
8 0.000833585 127.0.0.1 127.0.0.1 HTTP 654 GET /?code=4/zuPKCQlOvIcJq5gAvPRGLQdkiICNzOmAQUAx9apK5go HTTP/1.1
9 0.000841060 127.0.0.1 127.0.0.1 TCP 66 2807 → 45064 [ACK] Seq=1 Ack=589 Win=44928 Len=0 TSval=7233868 TSecr=7233868
10 45.005118503 127.0.0.1 127.0.0.1 TCP 66 [TCP Keep-Alive] 45064 → 2807 [ACK] Seq=588 Ack=1 Win=43776 Len=0 TSval=7245120 TSecr=7233868
11 45.005166221 127.0.0.1 127.0.0.1 TCP 66 [TCP Keep-Alive ACK] 2807 → 45064 [ACK] Seq=1 Ack=589 Win=44928 Len=0 TSval=7245120 TSecr=7233868
Wie Sie sehen können, sendet mein Programm einen FIN-Flag, die in netcat nicht da ist. Wo gehe ich hier falsch?
Veröffentlichen Sie keine Bilder von Text! – Olaf
@Olaf Ich würde nicht ein Wireshark Screenshot ein Bild des Textes genau nennen. Sie können nicht einfach die Paketliste kopieren/einfügen, nicht leicht. – dbush
@dbush: Sie können es in eine Textdatei ablegen (nicht sicher, ob es überhaupt möglich ist, in die Zwischenablage zu schreiben). – Olaf